这是一个实现埃拉托斯特尼筛法的程序。
class PrimeGenerator
def self.get_primes_between( x, y)
sieve_array = Array.new(y) {|index|
(index == 0 ? 0 : index+1)
}
position_when_we_can_stop_checking = Math.sqrt(y).to_i
(2..position_when_we_can_stop_checking).each{|factor|
sieve_array[(factor).. (y-1)].each{|number|
sieve_array[number-1] = 0 if isMultipleOf(number, factor)
}
}
sieve_array.select{|element|
( (element != 0) && ( (x..y).include? element) )
}
end
def self.isMultipleOf(x, y)
return (x % y) == 0
end
end
现在我正在为一个“提交解决方案来消磨时间”的网站做这件事。我选择了 Ruby 作为我的实现语言,但我被声明超时了。我做了一些基准测试。
require 'benchmark'
Benchmark.bmbm do |x|
x.report ("get primes") { PrimeGenerator.get_primes_between(10000, 100000)}
end
ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-mswin32]
可以翻译为:Ruby 1.9.1p0(2009年1月30日修订版21907)[i386-mswin32]。L:\Gishu\Ruby>ruby prime_generator.rb
Rehearsal ----------------------------------------------
get primes 33.953000 0.047000 34.000000 ( 34.343750)
------------------------------------ total: 34.000000sec
user system total real
get primes 33.735000 0.000000 33.735000 ( 33.843750)
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]
可以翻译为:Ruby 1.8.6(2007年3月13日补丁级别0)[i386-mswin32]。Rehearsal ----------------------------------------------
get primes 65.922000 0.000000 65.922000 ( 66.110000)
------------------------------------ total: 65.922000sec
user system total real
get primes 67.359000 0.016000 67.375000 ( 67.656000)
所以我在C# 2.0 / VS 2008中重新做了这件事——> 722毫秒
现在这让我想到,是我的实现有问题,还是各种语言之间的性能差异如此之大?(我对1.9版本的Ruby VM感到惊讶...直到我不得不去和C#比较为止:)
更新: 结果证明这确实是我的“超越欧拉筛”的问题 :) 消除不必要的循环迭代 是主要的优化。如果有人对细节感兴趣,可以在这里阅读;反正这个问题太长了。