jjzjj

go - 基准不良结果

coder 2024-07-05 原文

所以我实现了并发的 Quicksort 算法(也没有)。现在我想比较一下时间。我写了这个:

func benchmarkConcurrentQuickSort(size int, b *testing.B) {
    A := RandomArray(size)
    var wg sync.WaitGroup
    b.ResetTimer()
    ConcurrentQuicksort(A, 0, len(A)-1, &wg)
    wg.Wait()
}

func BenchmarkConcurrentQuickSort500(b *testing.B) {
    benchmarkConcurrentQuickSort(500, b)
}
func BenchmarkConcurrentQuickSort1000(b *testing.B) {
    benchmarkConcurrentQuickSort(1000, b)
}
func BenchmarkConcurrentQuickSort5000(b *testing.B) {
    benchmarkConcurrentQuickSort(5000, b)
}
func BenchmarkConcurrentQuickSort10000(b *testing.B) {
    benchmarkConcurrentQuickSort(10000, b)
}
func BenchmarkConcurrentQuickSort20000(b *testing.B) {
    benchmarkConcurrentQuickSort(20000, b)
}
func BenchmarkConcurrentQuickSort1000000(b *testing.B) {
    benchmarkConcurrentQuickSort(1000000, b)
}

结果是这样的:

C:\projects\go\src\github.com\frynio\mysort>go test -bench=.
BenchmarkConcurrentQuickSort500-4               2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort1000-4              2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort5000-4              2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort10000-4             2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort20000-4             2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort1000000-4                 30          49635266 ns/op
PASS
ok      github.com/frynio/mysort        8.342s

我可以相信最后一个,但我绝对认为对 500 个元素的数组进行排序需要的时间超过 1ns。我究竟做错了什么?我很确定 RandomArray 会返回所需大小的数组,正如我们在上一个基准测试中看到的那样。为什么打印出 0.00 ns?

func RandomArray(n int) []int {
    a := []int{}
    for i := 0; i < n; i++ {
        a = append(a, rand.Intn(500))
    }
    return a
}

// ConcurrentPartition - ConcurrentQuicksort function for partitioning the array (randomized choice of a pivot)
func ConcurrentPartition(A []int, p int, r int) int {
    index := rand.Intn(r-p) + p
    pivot := A[index]
    A[index] = A[r]
    A[r] = pivot
    x := A[r]
    j := p - 1
    i := p
    for i < r {
        if A[i] <= x {
            j++
            tmp := A[j]
            A[j] = A[i]
            A[i] = tmp
        }
        i++
    }
    temp := A[j+1]
    A[j+1] = A[r]
    A[r] = temp
    return j + 1
}

// ConcurrentQuicksort - a concurrent version of a quicksort algorithm
func ConcurrentQuicksort(A []int, p int, r int, wg *sync.WaitGroup) {
    if p < r {
        q := ConcurrentPartition(A, p, r)
        wg.Add(2)
        go func() {
            ConcurrentQuicksort(A, p, q-1, wg)
            wg.Done()
        }()
        go func() {
            ConcurrentQuicksort(A, q+1, r, wg)
            wg.Done()
        }()
    }
}

最佳答案

Package testing

A sample benchmark function looks like this:

func BenchmarkHello(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fmt.Sprintf("hello")
    }
}

The benchmark function must run the target code b.N times. During benchmark execution, b.N is adjusted until the benchmark function lasts long enough to be timed reliably.

我在您的代码中没有看到基准循环。尝试

func benchmarkConcurrentQuickSort(size int, b *testing.B) {
    A := RandomArray(size)
    var wg sync.WaitGroup
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        ConcurrentQuicksort(A, 0, len(A)-1, &wg)
        wg.Wait()
    }
}

输出:

BenchmarkConcurrentQuickSort500-4              10000        122291 ns/op
BenchmarkConcurrentQuickSort1000-4              5000        221154 ns/op
BenchmarkConcurrentQuickSort5000-4              1000       1225230 ns/op
BenchmarkConcurrentQuickSort10000-4              500       2568024 ns/op
BenchmarkConcurrentQuickSort20000-4              300       5808130 ns/op
BenchmarkConcurrentQuickSort1000000-4              1    1371751710 ns/op

关于go - 基准不良结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44742110/

有关go - 基准不良结果的更多相关文章

  1. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  2. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

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

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

  4. ruby - gem 推送结果为 "package metadata is missing" - 2

    我正在尝试将我更新的gem推送到ruby​​gems.com并得到以下结果。~/dev/V2/V2GPTI(master)$gembuildv2gpti.gemspecSuccessfullybuiltRubyGemName:v2gptiVersion:0.2File:v2gpti-0.2-universal-darwin-13.gem~/dev/V2/V2GPTI(master)$gempushv2gpti.gemspecERROR:Whileexecutinggem...(Gem::Package::FormatError)packagemetadataismissinginv2g

  5. ruby - 如何使用 omniauth/oauth 对每秒登录数进行基准测试? ( ruby +rspec) - 2

    我想用一个(自己的)omniauth提供商来衡量每秒可以登录多少次。我需要了解此omniauth/oauth请求的性能如何,以及此身份验证是否具有可扩展性?到目前为止我得到了什么:defperformance_auth(user_count=10)bm=Benchmark.realtimedouser_count.timesdo|n|forkdoclick_on'Logout'omniauth_config_mock(:provider=>"foo",:uid=>n,:email=>"foo#{n}@example.net")visit"/account/auth/foo/"enden

  6. ruby - 猴子修补 float 中缀运算符产生意想不到的结果 - 2

    重新定义Float#/似乎没有效果:classFloatdef/(other)"magic!"endendputs10.0/2.0#=>5.0但是当另一个中缀运算符Float#*被重新定义时,Float#/突然采用了新的定义:classFloatdef/(other)"magic!"enddef*(other)"spooky"endendputs10.0/2.0#=>"magic!"我很想知道是否有人可以解释这种行为的来源,以及其他人是否得到相同的结果。ruby:ruby2.0.0p353(2013-11-22)[x64-mingw32]要快速确认错误,请运行thisscript.

  7. ruby-on-rails - 尝试编辑时,Rails form_for 结果为 POST 而不是 PUT - 2

    我正在使用Rails4并遇到以下错误。RoutingErrorNoroutematches[POST]"/logs/1/meals/13/edit我正在使用:meal传递模型对象的form_for,并且编辑页面正确呈现。但是,Rails似乎并没有检查膳食对象是否已经保存,因此它一直尝试将表单发送到#create操作并尝试发出POST请求,而不是将表单发送到更新操作并进行当我点击提交时一个PUT请求。我如何让form_for识别我正在尝试更新现有对象并且需要PUT而不是POST?其他一切正常,我已经运行了所有迁移。我是Rails的新手,几乎一整天都在尝试自己解决这个问题。请帮忙!请注意,

  8. ruby-on-rails - 对 Rails 模型方法进行基准测试 - 2

    Rails中有类似RubyBenchmark的东西吗?我过去曾使用Ruby基准测试来比较不同的代码位,但没有一个与Rails相关。我想在一些基准测试中使用我的应用程序模型来做一些类似......#!/usr/bin/rubyrequire'benchmark'Benchmark.bmbmdo|x|x.report("Benchmark1")do1_000_000.timesdo#dosomethinghere...endendx.report("Benchmark2")do1_000_000.timesdo#Dosomethingelsehere...endendend这给了我这样的输

  9. ruby - 为什么会.is_a?和 .class 给出相互矛盾的结果? - 2

    我有三个属于同一个类的对象。一个是通过Item.new创建的,另外两个是从数据库(Mongoid)中提取的。我将这些对象中的一个/任何一个传递给另一个方法,并通过is_a?检查该方法中的类型:definitialize(item,attrs=nil,options=nil)super(attrs,options)raise'invaliditemobject'unlessitem.is_a?(Item)好吧,这次加薪被击中了。所以我在Rails控制台中检查类、is_a和instance_of。我得到相互矛盾的结果。为什么它们有相同的class但只有其中一个是那个class的instan

  10. ruby - 带有位串的意外解包结果 - 2

    为什么当我打开irb并运行时放'A'.unpack("B8")我得到01000001但是当我运行放'A'.unpack("B4B4")我只得到0100而不是[0100,0001]?unpack的分辨率是不是只有一个完整的字节?一点都不差? 最佳答案 让我们做一些测试来理解行为:>'A'.unpack('B8')=>["01000001"]它返回char'A'的8个最高有效位(MSB)>'A'.unpack('B4')=>["0100"]它返回char'A'的4MSBs>'A'.unpack('B16')=>["01000001"]它

随机推荐