gpt4 book ai didi

ruby - Fixnum#to_s 性能问题

转载 作者:数据小太阳 更新时间:2023-10-29 08:20:04 26 4
gpt4 key购买 nike

我有以下算法(它搜索二进制表示也是回文的回文):

#!/usr/bin/env ruby
class Runner
attr_accessor :min, :max, :sum

def initialize(min, max)
@sum = 0
@min, @max = min, max
end

def run
current = @min
while current <= @max
string = current.to_s
if string == string.reverse && current.to_s(2) == current.to_s(2).reverse
@sum += current
end
current += 1
end
puts @sum
end
end

t1 = Time.now
Runner.new(*ARGV.first.split(/\.+/).map(&:to_i)).run
puts "Time spent: #{(Time.now - t1).round(2)} s."

我在 10..10_000_000 范围内运行它。我在上面提供的版本导致:

Time spent: 2.55 s.

但如果我改变

    while current <= @max
string = current.to_s
if string == string.reverse && current.to_s(2) == current.to_s(2).reverse

    while current <= @max
string = current.to_s
string_b = current.to_s(2)
if string == string.reverse && string_b == string_b.reverse

然后我得到

Time spent: 6.25 s.

虽然我希望它会更快(需要更少的计算),但它却慢了两倍。同时,没有参数的#to_s 按预期工作,如果我删除变量并执行两次计算:

    while current <= @max
if current.to_s == current.to_s.reverse && current.to_s(2) == current.to_s(2).reverse

然后它工作得更慢

Time spent: 4.17 s.

查看 source of #to_s除了问题与条件的 else 分支有关外,对理解它没有帮助。但我在 rb_scan_args 中找不到问题或 NUM2INT任何一个。谁能解释为什么它以这种方式工作(我使用 MRI 2.1.1p76)?

最佳答案

在 Ruby 中,当你有这样的表达式时

a && b

a 首先求值,如果为假,则 b 不求值。

Base10 回文很少见,因此对于循环中的绝大多数循环,原始代码仅检查 string == string.reverse 是否为 false,然后继续进行下一次迭代环形。因此,您只执行一次 to_sto_s(2) 几乎从不执行。

其他组的更改都更频繁地调用 to_s,因此做更多的工作,因此速度更慢。我似乎并不感到惊讶。

关于ruby - Fixnum#to_s 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27265723/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com