Ruby程序几乎所有的时间都是从sys时间开始的?
我正在做一个关于欧拉问题的项目。但是我的电脑需要很长时间(上次是30分钟)才能得到答案 在Linux PC上执行time命令时,我得到的结果如下:Ruby程序几乎所有的时间都是从sys时间开始的?,ruby,Ruby,我正在做一个关于欧拉问题的项目。但是我的电脑需要很长时间(上次是30分钟)才能得到答案 在Linux PC上执行time命令时,我得到的结果如下: real 1m42.417s user 0m18.204s sys 1m24.026s 这是一个基于比所问问题小得多的数据集的时间 所以我的问题是,这次的结果是否表明我可以做一些事情来优化我的程序。我的猜测是,GC大部分时间都在工作,或者ruby的一些标准库函数需要花费太长的时间。另外,请注意,没有太多的I/O涉及,该程序将打印结果
real 1m42.417s
user 0m18.204s
sys 1m24.026s
这是一个基于比所问问题小得多的数据集的时间
所以我的问题是,这次的结果是否表明我可以做一些事情来优化我的程序。我的猜测是,GC大部分时间都在工作,或者ruby的一些标准库函数需要花费太长的时间。另外,请注意,没有太多的I/O涉及,该程序将打印结果在最后
根据AboutRuby的反馈添加配置文件结果:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
66.03 9.70 9.70 10508 0.92 1.26 Array#find_index
24.10 13.24 3.54 1027032 0.00 0.00 Fixnum#==
4.90 13.96 0.72 1046 0.69 13.38 Array#each
1.97 14.25 0.29 525 0.55 29.05 Integer#upto
0.61 14.34 0.09 9322 0.01 0.01 BasicObject#!=
0.48 14.41 0.07 7733 0.01 0.01 Fixnum#%
0.34 14.46 0.05 10508 0.00 0.00 BasicObject#==
0.27 14.50 0.04 10715 0.00 0.00 Fixnum#/
0.27 14.54 0.04 523 0.08 1.19 Object#find_div
0.20 14.57 0.03 8411 0.00 0.00 Fixnum#>=
0.14 14.59 0.02 8383 0.00 0.00 Fixnum#<=
0.14 14.61 0.02 526 0.04 0.04 Class#new
0.14 14.63 0.02 523 0.04 0.10 Enumerable.inject
0.14 14.65 0.02 3206 0.01 0.01 Array#<<
0.14 14.67 0.02 11245 0.00 0.00 Fixnum#+
0.07 14.68 0.01 523 0.02 0.02 Fixnum#>
0.07 14.69 0.01 8134 0.00 0.00 Fixnum#-
0.00 14.69 0.00 4 0.00 0.00 IO#set_encoding
0.00 14.69 0.00 523 0.00 0.00 Float#floor
0.00 14.69 0.00 523 0.00 0.00 Math.sqrt
0.00 14.69 0.00 523 0.00 0.00 Fixnum#to_f
0.00 14.69 0.00 5 0.00 0.00 Module#method_added
0.00 14.69 0.00 526 0.00 0.00 Array#initialize
0.00 14.69 0.00 1 0.00 700.00 Object#find_abundants
0.00 14.69 0.00 2 0.00 0.00 Kernel.require
0.00 14.69 0.00 523 0.00 26.71 Object#can_sum
0.00 14.69 0.00 2 0.00 0.00 Kernel.gem_original_require
0.00 14.69 0.00 73 0.00 0.00 Hash#default
0.00 14.69 0.00 1 0.00 13990.00 Object#search_for_can
0.00 14.69 0.00 246 0.00 0.00 Fixnum#to_s
0.00 14.69 0.00 246 0.00 0.00 Kernel.inspect
0.00 14.69 0.00 1 0.00 0.00 Array#inspect
0.00 14.69 0.00 1 0.00 0.00 Kernel.p
0.00 14.69 0.00 1 0.00 14690.00 #toplevel
可能可以用于进一步的加速,或者尝试改进算法?几乎所有的Project Euler问题(至少是我所知道的问题)都可以用任何编程语言在合理的时间内解决。您的程序运行需要30分钟,这表明您的算法不好。好吧,sys中的大部分时间通常表明它正在等待IO。然而,如果你说IO不多,那可能不是问题所在。然而,它仍在sys中花费大量时间,因此建议进行一些其他系统调用 如果你正在制作大量的对象,那么释放所有这些对象需要时间。它是否打印结果,然后在最终返回shell之前花时间完成?我曾经遇到过这样一个问题,一个爬行程序进入了一个糟糕的循环,最终使用了将近4千兆的内存。那个程序花了几分钟才关闭
您可以做的另一件事是程序,以及程序的一小部分。您还可以运行以查看运行最多的代码。根据探查器的结果,看起来像数组#find_index,可能我会尝试哈希?目前还不确定如何进行基准测试。而且,对我来说,为很多对象分配内存的时间也不多。我的观点是,当我认为有必要时,我将进一步改进我的算法,从sys time获得前5倍的速度。我意识到,最终数据的数据结构是什么(数组、集合、散列)比一个更好的算法更重要。在阅读了其他人如何实现他们的算法后,我重写了我的算法。我的新程序实际上只需几秒钟就可以运行,而无需进行太多优化。所以我想你是对的,先生,在我的例子中,算法比数据结构或其他语言实现细节更重要。使用集合而不是数组作为包含?根据这个函数:最终得到了大约十倍的速度,是懒惰的,并将结果提交给Project Euler,结果是正确的。
% cumulative self self total
time seconds seconds calls ms/call ms/call name
30.19 19.52 19.52 4313353 0.00 0.01 Set#include?
28.38 37.87 18.35 56246 0.33 0.68 Hash#each_key
15.96 48.19 10.32 28125 0.37 2.97 Integer#upto
7.55 53.07 4.88 271292 0.02 0.02 Set#add
6.40 57.21 4.14 4313353 0.00 0.00 Hash#include?
2.23 58.65 1.44 28123 0.05 0.85 Object#find_div
1.52 59.63 0.98 271292 0.00 0.00 Hash#[]=
1.28 60.46 0.83 56246 0.01 0.69 Set#each
1.25 61.27 0.81 56253 0.01 0.04 Class#new
1.16 62.02 0.75 237659 0.00 0.00 Fixnum#+
1.08 62.72 0.70 28125 0.02 0.05 Set#initialize
0.84 63.26 0.54 28124 0.02 0.18 Enumerable.inject
0.63 63.67 0.41 28123 0.01 0.02 Math.sqrt
0.23 63.82 0.15 28125 0.01 0.01 Hash#initialize
0.22 63.96 0.14 28123 0.00 1.23 Object#can_sum
0.19 64.08 0.12 28123 0.00 0.00 Float#floor
0.17 64.19 0.11 2 55.00 115.00 Array#each
0.15 64.29 0.10 1 100.00 210.00 Array#inspect
0.14 64.38 0.09 56246 0.00 0.00 Kernel.block_given?
0.12 64.46 0.08 28123 0.00 0.00 Fixnum#to_f
0.12 64.54 0.08 28124 0.00 0.00 NilClass#nil?
0.12 64.62 0.08 6966 0.01 0.02 Kernel.inspect
0.05 64.65 0.03 6966 0.00 0.00 Fixnum#to_s
0.00 64.65 0.00 3 0.00 0.00 Array#initialize
0.00 64.65 0.00 1 0.00 0.00 Kernel.respond_to?