浮点数转换在许多地方都有应用,例如 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 生成多项式近似值(这不是通过与项目本身相同的许可证分发的项目)。请告诉我是否会成为问题...
7条答案
按热度按时间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.bgibtngc2#
你好,谢谢你的评论。由于我在上面的基准测试中没有指定$x_{
-count 10
}$,所以我不得不重新运行基准测试。左边是标准库,右边是我的库。$x_{
}$
biswetbf3#
@sugawarayuuta 这个很棒!感谢分享。如果你能发送一个更改来优化strconv包,那就太好了。如果你还没有看到如何为Go做出贡献,请查看https://go.dev/doc/contribute。谢谢!
wztqucjr4#
CC @griesemer
dfddblmv5#
嗨,有点不幸。我尝试将我的解析器应用于
strconv
,确实变得更快了。然而,在经过几个小时的实验后,似乎并不是转换(主要算法)变快了,而是读取部分变快了......很抱歉我没有注意到这个问题,但既然我已经确认只更改
readFloat
就可以显著提高atof_test.go
中的所有基准测试速度,我可以发送一个涵盖读取部分的更改吗?我应该编辑这个问题还是创建一个新的问题?谢谢......kiz8lqtg6#
@sugawarayuuta 做的很好,谢谢。请继续发送关于readFloat的更改,我们很感激并期待与您就您的更改进行互动!稍后,如果有足够的时间,我们可以找出如何完全转换您的工作以适应整个ParseFloat。
3pvhb19x7#
https://go.dev/cl/572235提到了这个问题:
strconv: simplify and optimize the logic of readFloat