【问题标题】:Extracting rounding parameters from a set of float values从一组浮点值中提取舍入参数
【发布时间】:2020-09-23 13:42:42
【问题描述】:

给定以下浮点值:

n00.0, n0.0, n.0, 0.n, 0.0n, 0.00n, 0.000n 

其中 n 可以是 1、2 或 5,提取相应整数值用作舍入参数的最聪明、最快的方法是什么

-2, -1, 0, 1, 2, 3, 4 

目前,我正在使用哈希表:我认为速度很快,但不是那么聪明!

【问题讨论】:

  • 我目前使用 Crystal-Lang(或 Ruby)。目前的浮点值,但可以是字符串。
  • Number#humanize 的实现应该能给我们一些启示:github.com/crystal-lang/crystal/blob/…
  • -Math.log10(value).floor 成功了!比哈希快 60 倍以上。谢谢

标签: ruby crystal-lang floating-point-conversion


【解决方案1】:

我认为使用哈希是一种很好的方法,并且怀疑它是否会被 -Math.log10(k).floor 所超越,因此我运行了以下基准测试。

构造哈希

h = { 100.0=>-2, 10.0=>-1, 1.0=>0, 0.1=>1, 0.01=>2,
      200.0=>-2, 20.0=>-1, 2.0=>0, 0.2=>1, 0.02=>2,
      500.0=>-2, 50.0=>-1, 5.0=>0, 0.5=>1, 0.05=>2 } 

为基准测试构建测试数组(1500 万个元素)

n = 1_000_000
(arr = h.keys.flat_map { |k| [k]*n }.shuffle).size
  #=> 15_000_000 
arr.first(10)
  #=> [20.0, 0.02, 5.0, 0.5, 0.02, 0.05, 500.0, 50.0, 50.0, 20.0] 
arr.last(10)
  #=> [500.0, 0.5, 0.1, 20.0, 0.01, 0.1, 500.0, 50.0, 0.05, 0.5] 

执行基准测试

require 'fruity'

compare(
  hash:  -> { arr.each { |k| h[k] } },
  log10: -> { arr.each { |k| -Math.log10(k).floor } }
)
Running each test once. Test will take about 42 seconds.
hash is faster than log10 by 60.0% ± 10.0%

【讨论】:

  • 将您的基准测试移植到 Crystal 并且哈希似乎仍然慢了 4 倍,但我不是 100% 确信我在所有代码消除中欺骗了 LLVM(最天真的移植让它意识到了结果log10 操作永远不会被读取,只是完全消除它,这可能是 60x 评论的来源)。
  • 请注意,这个问题也用水晶语言标记。 Crystal 是一种作为LLVM 前端实现的编程语言,请参阅crystal-lang.org
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多