jjzjj

go - Go sync.pool 比 make 慢很多吗?

coder 2024-07-12 原文

我尝试使用sync.Pool 来重用[]byte。但事实证明它比 make 慢。代码:

package main

import (
    "sync"
    "testing"
)

func BenchmarkMakeStack(b *testing.B) {
    for N := 0; N < b.N; N++ {
        obj := make([]byte, 1024)
        _ = obj
    }
}

var bytePool = sync.Pool{
    New: func() interface{} {
        b := make([]byte, 1024)
        return &b
    },
}

func BenchmarkBytePool(b *testing.B) {
    for N := 0; N < b.N; N++ {
        obj := bytePool.Get().(*[]byte)
        _ = obj
        bytePool.Put(obj)
    }
}

结果:

$ go test pool_test.go -bench=. -benchmem
BenchmarkMakeStack-4    2000000000      0.29 ns/op       0 B/op    0 allocs/op
BenchmarkBytePool-4      100000000     17.2 ns/op        0 B/op    0 allocs/op

根据 Go 文档,sync.Pool 应该更快,但我的测试显示并非如此。谁能帮我解释一下?

更新: 1. 使用 go benchmark 更新有问题的代码。 2.答案放在stackheap,看peterSO的答案。

最佳答案

基准测试第一定律:无意义的微基准测试产生无意义的结果。

您不切实际的微基准测试没有意义。


Package sync

import "sync"

type Pool

A Pool is a set of temporary objects that may be individually saved and retrieved.

Any item stored in the Pool may be removed automatically at any time without notification. If the Pool holds the only reference when this happens, the item might be deallocated.

A Pool is safe for use by multiple goroutines simultaneously.

Pool's purpose is to cache allocated but unused items for later reuse, relieving pressure on the garbage collector. That is, it makes it easy to build efficient, thread-safe free lists. However, it is not suitable for all free lists.

An appropriate use of a Pool is to manage a group of temporary items silently shared among and potentially reused by concurrent independent clients of a package. Pool provides a way to amortize allocation overhead across many clients.

An example of good use of a Pool is in the fmt package, which maintains a dynamically-sized store of temporary output buffers. The store scales under load (when many goroutines are actively printing) and shrinks when quiescent.

On the other hand, a free list maintained as part of a short-lived object is not a suitable use for a Pool, since the overhead does not amortize well in that scenario. It is more efficient to have such objects implement their own free list.

sync.Pool 是否适合您的用例? sync.Pool 是否适合您的基准测试?您的用例和基准是否相同?您的用例是微基准测试吗?


使用 Go testing 包进行人工基准测试,使用单独的基准测试 make 堆栈和堆分配,make 既快又慢比 sync.Pool

输出:

$ go test pool_test.go -bench=. -benchmem
BenchmarkMakeStack-4    2000000000      0.29 ns/op       0 B/op    0 allocs/op
BenchmarkMakeHeap-4       10000000    136 ns/op       1024 B/op    1 allocs/op
BenchmarkBytePool-4      100000000     17.2 ns/op        0 B/op    0 allocs/op
$

pool_test.go:

package main

import (
    "sync"
    "testing"
)

func BenchmarkMakeStack(b *testing.B) {
    for N := 0; N < b.N; N++ {
        obj := make([]byte, 1024)
        _ = obj
    }
}

var obj []byte

func BenchmarkMakeHeap(b *testing.B) {
    for N := 0; N < b.N; N++ {
        obj = make([]byte, 1024)
        _ = obj
    }
}

var bytePool = sync.Pool{
    New: func() interface{} {
        b := make([]byte, 1024)
        return &b
    },
}

func BenchmarkBytePool(b *testing.B) {
    for N := 0; N < b.N; N++ {
        obj := bytePool.Get().(*[]byte)
        _ = obj
        bytePool.Put(obj)
    }
}

关于go - Go sync.pool 比 make 慢很多吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53613556/

有关go - Go sync.pool 比 make 慢很多吗?的更多相关文章

  1. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  2. ruby - 无法安装 gem - make 未被识别为内部或外部命令可运行程序或批处理文件 - 2

    我想在Windows7上安装带有ruby​​1.9.3的rspec-railsgem。我收到一些错误消息,提示无法安装某些json库。所以,我使用下面的说明来解决它。来源=The'json'nativegemrequiresinstalledbuildtools从[rubyinstaller.org][3]下载[Ruby1.9.3][2]从[rubyinstaller.org][3]下载DevKit文件对于Ruby1.9.3,使用[DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe][4]将DevKit解压到路径C:\Ruby193\DevKit运行cd

  3. ruby-on-rails - Rspec 测试属于并且有很多 - 2

    我正在运行rspec测试以确保两个模型通过has_many和belongs_to相互关联。下面是我的测试。describe"testingforhasmanylinks"dobeforedo@post=Post.new(day:"Day1",content:"Test")@link=Link.new(post_id:@post.id,title:"google",url:"google.com")endit"inthepostmodel"do@post.links.first.url.should=="google.com"endend测试告诉我url是一个未定义的方法。我的测试有什么

  4. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  5. ruby - 无法在 MacOS 10.14.2 Mojave : Error running '__rvm_make -j4' 上使用 RVM 安装任何 Ruby - 2

    将MacOS升级到10.14.2Mojave后,我无法再使用RVM安装任何Ruby版本。它总是给出这样的错误:$rvminstall2.5.3ruby-2.5.3-#removingsrc/ruby-2.5.3..Searchingforbinaryrubies,thismighttakesometime.Nobinaryrubiesavailablefor:osx/10.14/x86_64/ruby-2.5.3.Continuingwithcompilation.Pleaseread'rvmhelpmount'togetmoreinformationonbinaryrubies.Ch

  6. ruby-on-rails - 无方法错误 : undefined method `get' when running rspec and making get/visit calls - 2

    我完全被困在这里,希望有人能指出我正确的方向。我正在尝试使用rspec来测试我的网络路由。我按照这里的例子:https://www.relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec我的规范文件被命名为:spec/requests文件夹中的api_tests_spec.rb。文件如下:require'spec_helper'describe"APITests"dodescribe"GET/regions"doit"shouldreturnavalidresponse"do#Runthegeneratoragai

  7. ruby-on-rails - ruby + Mongoid : how to make a required field? - 2

    我使用Mongoid的githead版本(因为Rails4),我想制作一个字段必填文档:classMyClassincludeMongoid::Documentfield:name,type:String,required:true我有这个错误:Problem:Invalidoption:requiredprovidedforfield:name.Summary:Mongoidrequiresthatyouonlyprovidevalidoptionsoneachfielddefinitioninordertopreventun...我做错了什么? 最佳答案

  8. ruby - 在 OSX 10.8.4 上使用无法识别的选项 '-arch' 安装 json-1.8.0 时 make 失败 - 2

    我正在尝试正确设置我的ruby​​环境,但在尝试bundleinstall我的测试应用程序时不断收到错误。我在尝试bundleinstall时第一次遇到错误:$railsnewapp//[...]runbundleinstallFetchinggemmetadatafromhttps://rubygems.org/..Resolvingdependencies...Usingrake(10.1.0)Usingi18n(0.6.5)Usingmulti_json(1.7.9)Usingactivesupport(3.2.9)Usingbuilder(3.0.4)Usingactivemo

  9. ruby-on-rails - 在 Sinatra 中使用 Rack::Session::Pool - 2

    我正在探索Sinatra,我想使用session,但我不想将它们存储在Cookie中,我发现Rack::Session::Pool效果很好。现在我希望session在一定持续时间后过期,但我不明白如何实例化Rack::Session::Pool并且他们在Sinatra中使用它。有什么线索吗? 最佳答案 Sinatra非常强大,TheWickedFlea的技巧没有奏效,但这个确实奏效了:useRack::Session::Pool,:domain=>'example.com',:expire_after=>60*60*24*365谢谢

  10. ruby - 为什么mac下Ruby下有很多 "fsevent_watch"的实例? - 2

    现在我有21个“fsevent_watch”实例,其父进程和进程组是“ruby”。我正在开发一个Rails项目,但目前没有任何项目在运行。我之前启动的服务器是使用cntrl+C关闭的。我在Mac上。它是如何创建的?ruby应用关闭后不应该关闭吗? 最佳答案 这是由在您的Rails应用程序后台运行的spring服务器引起的。您可以通过以下方式检查spring状态,springstatus然后,停止spring服务器,springstop这将终止/关闭您看到的所有事件进程。 关于ruby-为

随机推荐