jjzjj

performance - 内置追加与 bytes.Buffer 写入

coder 2023-06-27 原文

在我需要将未知数量的数据添加到一个字节的情况下,比方说在一个循环中,我可以使用内置函数 append() 或创建一个新的Buffer 并使用 Write() 函数。

哪种方法最快?

最佳答案

这取决于用例。
在这两种情况下,bytes.Buffer 都比 append 快(示例:1、2、3、4)。

使用 buf.Write(make([]byte, 16)) 需要 4.6482659s,
使用 buf = append(buf, make([]byte, 16)...) 需要 6.6623811s

对于示例 5、6:
使用 buf = append(buf, byte(i)) 需要 445.0255ms,
使用 buf.WriteByte(byte(i)) 需要 1.4410824s


并且 bytes.Buffer 使用内置函数 copy 并且速度很快:

// Write appends the contents of p to the buffer, growing the buffer as
// needed. The return value n is the length of p; err is always nil. If the
// buffer becomes too large, Write will panic with ErrTooLarge.

func (b *Buffer) Write(p []byte) (n int, err error) {
  b.lastRead = opInvalid
  m := b.grow(len(p))
  return copy(b.buf[m:], p), nil
}

bytes.Buffer 需要 4.8892797s 而 append 需要 7.7514434s

查看这些基准:

1- 使用 append:

package main

import (
    "fmt"
    "time"
)

func main() {
    buf := []byte{}
    data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    t := time.Now()
    for i := 0; i < 100000000; i++ {
        buf = append(buf, data...)
    }
    fmt.Println(time.Since(t))
    fmt.Println(len(buf))
}

输出:

7.7514434s
1600000000

2- 使用 bytes.Buffer

package main

import (
    "bytes"
    "fmt"
    "time"
)

func main() {
    buf := &bytes.Buffer{}
    data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    t := time.Now()
    for i := 0; i < 100000000; i++ {
        buf.Write(data)
    }
    fmt.Println(time.Since(t))
    fmt.Println(buf.Len())
}

输出:

4.8892797s
1600000000

3- 使用 bytes.Buffermake([]byte, 16):

package main

import (
    "bytes"
    "fmt"
    "time"
)

func main() {
    buf := &bytes.Buffer{}
    t := time.Now()
    for i := 0; i < 100000000; i++ {
        buf.Write(make([]byte, 16))
    }
    fmt.Println(time.Since(t)) // 4.6482659s
    fmt.Println(buf.Len())     //1600000000
}

4- 使用 appendmake([]byte, 16):

package main

import (
    "fmt"
    "time"
)

func main() {
    buf := []byte{}
    t := time.Now()
    for i := 0; i < 100000000; i++ {
        buf = append(buf, make([]byte, 16)...)
    }
    fmt.Println(time.Since(t)) // 6.6623811s
    fmt.Println(len(buf))      // 1600000000
}

5- 使用 buf = append(buf, byte(i)) 需要 445.0255ms:

package main

import (
    "fmt"
    "time"
)

func main() {
    buf := []byte{}
    t := time.Now()
    for i := 0; i < 100000000; i++ {
        buf = append(buf, byte(i))
    }
    fmt.Println(time.Since(t)) // 445.0255ms
    fmt.Println(len(buf))      // 100000000
}

6- 使用 buf.WriteByte(byte(i)) 需要 1.4410824s:

package main

import (
    "bytes"
    "fmt"
    "time"
)

func main() {
    buf := &bytes.Buffer{}

    t := time.Now()
    for i := 0; i < 100000000; i++ {
        buf.WriteByte(byte(i))
    }
    fmt.Println(time.Since(t)) // 1.4410824s
    fmt.Println(buf.Len())     // 100000000
}

并查看:

Appending to slice bad performance.. why?
Where is append() implementation?
Efficient appending to a variable-length container of strings (Golang)

关于performance - 内置追加与 bytes.Buffer 写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39319024/

有关performance - 内置追加与 bytes.Buffer 写入的更多相关文章

  1. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  2. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  3. ruby - Ruby 是否使用 $stdout 来写入 puts 和 return 的输出? - 2

    我想知道Ruby用来在命令行打印这些东西的输出流:irb(main):001:0>a="test"=>"test"irb(main):002:0>putsatest=>nilirb(main):003:0>a=>"test"$stdout是否用于irb(main):002:0>和irb(main):003:0>?而且,在这两次调用之间,$stdout的值是否有任何变化?另外,有人能告诉我打印/写入这些内容的Ruby源代码吗? 最佳答案 是的。而且很容易向自己测试/证明。在命令行试试这个:ruby-e'puts"foo"'>test.

  4. ruby - 是否有内置的 Ruby 1.8.7 将数组拆分为相同大小的子数组? - 2

    我已经开始了:defsplit_array(array,size)index=0results=[]ifsize>0whileindex如果我在[1,2,3,4,5,6]上运行它,比如split_array([1,2,3,4,5,6],3)它将产生这个数组:[[1,2,3],[4,5,6]]。在Ruby1.8.7中是否已经有可用的东西可以做到这一点? 最佳答案 [1,2,3,4,5,6].each_slice(3).to_a#=>[[1,2,3],[4,5,6]]对于1.8.6:require'enumerator'[1,2,3,4

  5. ruby-on-rails - Resque - 类的未定义方法 'perform' - 2

    我目前对后台队列不太满意。我正在尝试让Resque工作。我已经安装了redis和Resquegem。Redis正在运行。一个worker正在运行(rakeresque:workQUEUE=simple)。使用Web界面,我可以看到工作人员正在运行并等待工作。当我运行“rakeget_updates”时,作业已排队但失败了。我已经用defself.perform和defperform试过了。发条.raketask:get_updates=>:environmentdoResque.enqueue(GetUpdates)end类文件(app/workers/get_updates.rb)c

  6. Ruby:写入 stdin 并从 stdout 读取? - 2

    我正在编写一个ruby​​程序,它应该执行另一个程序,通过stdin向它传递值,从它的stdout读取响应,然后打印响应。这是我目前所拥有的。#!/usr/bin/envrubyrequire'open3'stdin,stdout,stderr=Open3.popen3('./MyProgram')stdin.puts"helloworld!"output=stdout.readerrors=stderr.readstdin.closestdout.closestderr.closeputs"Output:"puts"-------"putsoutputputs"\nErrors:"p

  7. Ruby -> 写入二维数组 - 2

    我正在处理http://prepwork.appacademy.io/mini-curriculum/array/中概述的数组问题我正在尝试创建函数my_transpose,它接受一个矩阵并返回其转置。我对写入二维数组感到很困惑!这是一个代码片段,突出了我的困惑。rows=[[0,1,2],[3,4,5],[6,7,8]]columns=Array.new(3,Array.new(3))putscolumns.to_s#Outputisa3x3arrayfilledwithnilcolumns[0][0]=0putscolumns.to_s#Outputis[[0,nil,nil],[

  8. ruby-on-rails - RoR中是否有任何内置方法可以为整数填充零? - 2

    如果我想要“00001”而不是“1”,除了我自己写填零方法之外,有没有内置的方法可以帮助我为整数填零? 最佳答案 puts"%05d"%1#00001参见:String::%,Kernel::sprintf这是正在发生的事情。%左侧的"%05d"是C风格的格式说明符。%右边的变量就是要格式化的东西。格式说明符可以像这样解码:%-格式说明符的开头0-用前导零填充5-长度为5个字符d-被格式化的是一个整数如果你要格式化多个东西,你会把它们放在一个数组中:"%d-%s"%[1,"One"]#=>1-one

  9. ruby - 使写入文件线程安全 - 2

    我在一个ruby​​文件中有一个函数可以像这样写入一个文件File.open("myfile",'a'){|f|f.puts("#{sometext}")}这个函数在不同的线程中被调用,使得像上面这样的文件写入不是线程安全的。有谁知道如何以最简单的方式使这个文件写入线程安全?更多信息:如果重要的话,我正在使用rspec框架。 最佳答案 您可以通过File#flock给锁File.open("myfile",'a'){|f|f.flock(File::LOCK_EX)f.puts("#{sometext}")}

  10. ruby-on-rails - RVM、Ruby 1.9.2、Rails 2.3.8、Passenger 和 "invalid byte sequence in US-ASCII" - 2

    我刚刚开始从Ruby1.8.7升级到Ruby1.9.2(使用RVM)。我的所有应用程序都使用“脚本/服务器”(或“rails服务器”)和1.9.2运行,但是,只有Rails3.0.0RC应用程序可以与Passenger一起使用。Rails2.3.8应用给出的错误信息是:invalidbytesequenceinUS-ASCII我猜这是一个Passenger问题。我使用找到的RVM指南安装了Passenger2.2.15here.任何想法如何修复这个错误?谢谢。我已更新以包含堆栈跟踪:/Users/kevin/.rvm/gems/ruby-1.9.2-p0/gems/actionpack

随机推荐