2015-01-21 55 views
6

我有一个复杂的对象,my_object,我与Mashalling在红宝石2.2.0慢2.1.5

Marshal.dump(my_object)编组

我已基准调用该线100的性能在这两个2.1.5p273和2.2.0,以及下面的时间是结果:

2.1.5 
        user  system  total  real 
Marshal Dump 7.310000 0.120000 7.430000 ( 8.988470) 
Marshal Dump 7.520000 0.050000 7.570000 ( 8.210356) 
Marshal Dump 7.610000 0.050000 7.660000 ( 8.432685) 

2.2.0 
        user  system  total  real 
Marshal Dump 26.480000 0.150000 26.630000 (29.591742) 
Marshal Dump 24.100000 0.300000 24.400000 (28.520397) 
Marshal Dump 26.210000 0.210000 26.420000 (29.993412) 

(我跑了基准3次,每次版本,以彻底)

正如你所看到的,它带我去在2.2.0比2.1.5中超过3倍。我对Marshal.dump进行了调整,因为使用ruby-prof宝石,它告诉我那是表现不佳的行;但是我找不到一种方法来获取Marshal.dump本身在探查器中调用的方法。

编辑:见我的答案以最小的摄制,多次实验

+1

对于那些想要遵循这一点的人,我将其缩减为最低限度的repro,并将其记录在此处:https://bugs.ruby-lang.org/issues/10761。这个问题似乎并不是规模,而是复杂性,因为我必须创建一个包含多层嵌套对象的对象来重现问题。 – davej 2015-01-21 05:15:52

+1

你编辑的方式使原始问题消失,这个问题......好吧,这不是一个问题,它基本上是一个答案。我认为整个事情很有趣,但对于SO标准,我认为它应该是一个倒退。 – iain 2015-01-21 16:31:00

+0

@ian:真的吗?我的选择留下了一个并没有真正帮助任何人的问题,或者发布了一些我认为是非常重要的问题,或者删除了整个问题。我做了我认为对社区最好的事情。坦率地说,像你这样的小事给了极客一个不好的代表。 – davej 2015-01-21 16:36:27

回答

4

源位置是nil后发现的。

Marshal.method(:dump).source_location 
#=> nil 

这意味着它是一个C实现的方法,并且没有更多的Ruby代码可以跟踪。换句话说,它是一种原子/基本的方法。

如果您认为您的结果是有效的,那么我建议您将其作为Ruby trunk中的错误发布。最新版本的Ruby确实发现了几个性能问题,所以你的情况似乎并不少见。

+0

感谢您的技术和建议。现在开始寻找一个微小的可重现版本的问题! – davej 2015-01-21 01:08:01

1

这是导致经济放缓的编组花车。

require 'benchmark' 

class ToBeMarshaled 

    def initialize n 
    @a = [] 
    n.times do |i| 
     @a << i.to_f 
    end 
    end 

end 

tbm = ToBeMarshaled.new(10000) 

n = 100 

Benchmark.bm do |x| 
    x.report("Marshal Dump") {for i in 1..n; Marshal.dump(tbm); end} 
end 

结果(RAN为每个红宝石版本基准3次):慢

2.1.5 
        user  system  total  real 
Marshal Dump 0.640000 0.010000 0.650000 ( 0.744080) 
Marshal Dump 0.670000 0.000000 0.670000 ( 0.758597) 
Marshal Dump 0.650000 0.020000 0.670000 ( 0.747583) 

2.2.0 
        user  system  total  real 
Marshal Dump 25.070000 0.220000 25.290000 (27.980023) 
Marshal Dump 24.100000 0.160000 24.260000 (26.633049) 
Marshal Dump 24.440000 0.230000 24.670000 (27.540826) 

〜35倍。

如果你走 “.to_f” 掉的代码,你会得到:

2.1.5 
        user  system  total  real 
Marshal Dump 0.160000 0.000000 0.160000 ( 0.180247) 
Marshal Dump 0.180000 0.000000 0.180000 ( 0.189485) 
Marshal Dump 0.160000 0.010000 0.170000 ( 0.191304) 

2.2.0 
        user  system  total  real 
Marshal Dump 0.120000 0.010000 0.130000 ( 0.146710) 
Marshal Dump 0.130000 0.010000 0.140000 ( 0.159851) 
Marshal Dump 0.130000 0.000000 0.130000 ( 0.143917) 

2.2.0稍微挤掉了2.1.5。