go strconv:使用新的refloat算法优化ParseFloat

xmjla07d  于 4个月前  发布在  Go
关注(0)|答案(7)|浏览(47)

浮点数转换在许多地方都有应用,例如 encoding/json 。虽然当前的 Eisel-Lemire 效率较高,但实际上可以使用更小的查找表并同时减少执行时间。
我从头开始用 Go 实现这个算法,现在它可以通过 BSD-3-Clause 许可证提供:https://github.com/sugawarayuuta/refloat

  • 基准测试
$ go test -bench "\d$" -benchmem -benchtime 1m
goos: linux
goarch: amd64
pkg: github.com/sugawarayuuta/refloat
cpu: Intel(R) Core(TM) i3-10110U CPU @ 2.10GHz
BenchmarkParseFloat64/strconv/bits-4            648877453              112.3 ns/op             0 B/op          0 allocs/op
BenchmarkParseFloat64/strconv/norm-4            729803588               95.37 ns/op            0 B/op          0 allocs/op
BenchmarkParseFloat64/refloat/bits-4            773428314               93.41 ns/op            0 B/op          0 allocs/op
BenchmarkParseFloat64/refloat/norm-4            1000000000              67.75 ns/op            0 B/op          0 allocs/op
BenchmarkParseFloat32/strconv/bits-4            894441672               82.30 ns/op            0 B/op          0 allocs/op
BenchmarkParseFloat32/strconv/norm-4            1000000000              67.97 ns/op            0 B/op          0 allocs/op
BenchmarkParseFloat32/refloat/bits-4            870175646               83.18 ns/op            3 B/op          0 allocs/op
BenchmarkParseFloat32/refloat/norm-4            1000000000              50.24 ns/op            0 B/op          0 allocs/op
PASS
ok      github.com/sugawarayuuta/refloat        612.972s
  • 观察结果

我们可以看到,它在正态分布( norm )浮点数和位运算均匀浮点数( bits )上表现得更好。
基准测试在多台机器上进行 - 它们产生的结果非常相似。
特别是正态分布 float64 有显著的变化(约41%),这将适用于许多实际应用场景。

  • 测试

通过了 parse-number-fxx-test-data ,标准库的测试,我还在进行积极的模糊测试,并将输出与当前的 strconv 进行比较。到目前为止,唯一检测到的问题似乎是 the issue 42436 ,这是 strconv 的问题。

  • 注意事项

我实际上使用 an external tool 生成多项式近似值(这不是通过与项目本身相同的许可证分发的项目)。请告诉我是否会成为问题...

9fkzdhlc

9fkzdhlc1#

Please add the output of golang.org/x/perf/cmd/benchstat comparing the benchmark output, run with -test.count=10 , for both the current package and the package with your change. Thanks.

bgibtngc

bgibtngc2#

你好,谢谢你的评论。由于我在上面的基准测试中没有指定$x_{-count 10}$,所以我不得不重新运行基准测试。左边是标准库,右边是我的库。

$x_{

│ ./strconv.txt │            ./refloat.txt            │
                    │    sec/op     │   sec/op     vs base                │
ParseFloat64/bits-4    104.85n ± 1%   92.11n ± 1%  -12.16% (p=0.000 n=10)
ParseFloat64/norm-4     95.04n ± 5%   68.89n ± 3%  -27.51% (p=0.000 n=10)
ParseFloat32/bits-4     80.86n ± 2%   84.44n ± 1%   +4.41% (p=0.000 n=10)
ParseFloat32/norm-4     65.97n ± 2%   48.88n ± 1%  -25.91% (p=0.000 n=10)
geomean                 85.39n        71.53n       -16.22%

                    │ ./strconv.txt │         ./refloat.txt          │
                    │     B/op      │    B/op     vs base            │
ParseFloat64/bits-4    0.000 ± 0%     0.000 ± 0%  ~ (p=1.000 n=10) ¹
ParseFloat64/norm-4    0.000 ± 0%     0.000 ± 0%  ~ (p=1.000 n=10) ¹
ParseFloat32/bits-4    0.000 ± 0%     3.000 ± 0%  ? (p=0.000 n=10)
ParseFloat32/norm-4    0.000 ± 0%     0.000 ± 0%  ~ (p=1.000 n=10) ¹
geomean                           ²               ?                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                    │ ./strconv.txt │            ./refloat.txt            │
                    │   allocs/op   │ allocs/op   vs base                 │
ParseFloat64/bits-4    0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
ParseFloat64/norm-4    0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
ParseFloat32/bits-4    0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
ParseFloat32/norm-4    0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
geomean                           ²               +0.00%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

}$

biswetbf

biswetbf3#

@sugawarayuuta 这个很棒!感谢分享。如果你能发送一个更改来优化strconv包,那就太好了。如果你还没有看到如何为Go做出贡献,请查看https://go.dev/doc/contribute。谢谢!

dfddblmv

dfddblmv5#

嗨,有点不幸。我尝试将我的解析器应用于strconv,确实变得更快了。然而,在经过几个小时的实验后,似乎并不是转换(主要算法)变快了,而是读取部分变快了......
很抱歉我没有注意到这个问题,但既然我已经确认只更改readFloat就可以显著提高atof_test.go中的所有基准测试速度,我可以发送一个涵盖读取部分的更改吗?我应该编辑这个问题还是创建一个新的问题?谢谢......

kiz8lqtg

kiz8lqtg6#

@sugawarayuuta 做的很好,谢谢。请继续发送关于readFloat的更改,我们很感激并期待与您就您的更改进行互动!稍后,如果有足够的时间,我们可以找出如何完全转换您的工作以适应整个ParseFloat。

3pvhb19x

3pvhb19x7#

https://go.dev/cl/572235提到了这个问题:strconv: simplify and optimize the logic of readFloat

相关问题