Toxic Elephant

Some thoughts on Ruby's speed

Posted by matijs 02/03/2013 at 16h42

Yesterday, I read Alex Gaynor’s slides on dynamic language speed. It’s an interesting argument, but I’m not totally convinced.

At a high level, the argument is as follows, it seems:

  • For a comparable algorithm, Ruby et al. do much more work behind the scenes than ‘fast’ languages such as C.
  • In particular, they do a lot of memory allocation.
  • Therefore, we should add tools to those languages that allow us to do memory allocation more efficiently.

Allocation

As an example, the creation of an array of squared integers is presented, where the runtime needs to dynamically allocate ever larger arrays to hold its result.

I can see the argument there, but I’m not convinced the solution is correct, for the example given. In particular, how much time is spent allocating and re-allocating the array of object references, and how much is spent elsewehere?

require 'benchmark'

def doubles_unallocated n
  buf = []
  i = 1; j = 0
  while j < n do
    buf[i - 1] = i * i
    i += 1; j += 1
  end
  buf
end

def doubles_preallocated n
  buf = Array.new n
  i = 1; j = 0
  while j < n do
    buf[j] = i * i
    i += 1; j += 1
  end
  buf
end

n = 10000

Benchmark.bmbm do |x|
  x.report("unallocated") { n.times { doubles_unallocated 1000 } }
  x.report("preallocated") { n.times { doubles_preallocated 1000 } }
end

A typical result on Ruby 1.9.3 would be (I’m not showing the rehearsal section here):

                   user     system      total        real
unallocated    1.480000   0.020000   1.500000 (  1.493959)
preallocated   1.370000   0.030000   1.400000 (  1.404668)

Taking several runs into account, I conclude that pre-allocating the array shaves off 7 to 13 percent of the runtime.

Algorithms

The algorithms used above are obviously not idiomatic Ruby, but they have the advantage of allowing a comparison of allocated and unallocated arrays. Normally, I would probably use map with a range. Similarly, the Python code presented in the slides looks odd to me. I would have expected something using list comprehensions.

Here is the idiomatic Ruby implementation:

def doubles_map n
  (1..n).map {|i| i * i }
end

And here is the Ruby equivalent of the Python example given (using each versus for gives no difference in speed):

def doubles_each n
  buf = []
  (1..n).each do |i|
    buf << i * i
  end
  buf
end

For Ruby, doubles_map is the idiomatic implementation. It also has the advantage that a dedicated implementation of Range#map would be able to allocate the result array in one go, transparantly avoiding the array growing overhead. Using list comprehensions in Python would probably have the same advantage.

Unfortunately, doubles_map is also a lot slower than doubles_each, except on MRI 1.8. Here is the benchmark I ran with a fixed-array version thrown in for good measure:

ARR = (1..1000).to_a
def doubles_fixed_array
  ARR.map {|i| i * i }
end

n = 10000

Benchmark.bmbm do |x|
  x.report("using map") { n.times { doubles_map 1000 } }
  x.report("using each") { n.times { doubles_each 1000 } }
  x.report("using a fixed array") { n.times { doubles_fixed_array } }
end

Here is the result for MRI 1.9.3:

                          user     system      total        real
using map             1.220000   0.000000   1.220000 (  1.217607)
using each            1.070000   0.020000   1.090000 (  1.091302)
using a fixed array   0.940000   0.020000   0.960000 (  0.969685)

And for MRI 1.8.7:

                          user     system      total        real
using map             2.790000   0.000000   2.790000 (  2.795956)
using each            3.630000   0.010000   3.640000 (  3.644272)
using a fixed array   2.120000   0.010000   2.130000 (  2.133636)

A better Range#map

These benchmark results made me wonder how Range#map is implemented. Since it is written in Ruby, I checked the Rubinius implementation, and there at least the problem seems due to the lack of a dedicated Range#map implementation: The generic Enumerable#map is used, effectively turning it into doubles_each. I’m not entirely sure why it is actually slower, perhaps that’s due to the double yield involved and/or argument splatting.

Here are the results of the previous benchmark, run on Rubinius 2.0.0-rc1:

                          user     system      total        real
using map             1.312082   0.004000   1.316082 (  1.316717)
using each            0.996062   0.000000   0.996062 (  0.997418)
using a fixed array   0.720045   0.000000   0.720045 (  0.724615)

I made the following simple dedicated implementation for Range#map. It falls back to the default Enumerable#map for most cases, except for Fixnums:

class Range
  def map
    if block_given? && Fixnum === @begin
      first, last = @begin, @end
      last -= 1 if @excl
      size = last - first + 1

      out = Array.new size
      out_tuple = out.tuple

      i = first
      j = 0
      while i <= last
        out_tuple[j] = yield i
        i += 1
        j += 1
      end

      out
    else
      super
    end
  end
end

This makes doubles_map run slightly faster than the fixed array version:

                          user     system      total        real
using map             0.648040   0.000000   0.648040 (  0.650103)
using each            0.928058   0.000000   0.928058 (  0.930109)
using a fixed array   0.680042   0.004001   0.684043 (  0.686719)

Benchmarking Still Needed

While examining these options, I found that there are many ways to write this code, each subtly different, each with a different performance on different Rubies (the examples using while are the slowest on MRI 1.9.3, but the fastest on Rubinus). So, if you really want your code to be fast, you still have to benchmark, you still have to know which Ruby implementation your code will run on, and you still have to try all the options.

Posted in  | Tags , ,  | 36 comments | no trackbacks

Comments

  1. %>

    weislessiot said 05/03/2013 at 00h55 later:

    Aw, this was a honestly nice post. In idea I would like to put in writing like this furthermore - taking time and actual effort to make a really wonderful article?- but what can I say?- I procrastinate alot and by no means seem to get some thing accomplished.

    christian louboutin shoes

  2. %>

    christian louboutin pigalle said 06/03/2013 at 07h31 later:

    This is one awesome blog.Really thank you! Great.

  3. %>

    christian louboutin bridal shoes said 06/03/2013 at 09h48 later:

    Every word in this piece of work is very clear and your passion for this topic shines. Please continue your work in this area and I hope to see more from you in the future.

  4. %>

    christian louboutin slingbacks said 06/03/2013 at 11h26 later:

    I like this web blog very much, Its a rattling nice situation to read and obtain info . “‘Taint’t worthwhile to wear a day all out before it comes.” by Sarah Orne Jewett

  5. %>

    FedeNigeeduct said 07/03/2013 at 02h31 later:

    really nice post, i definitely love this web page, keep on it

    nfl throwback jerseys

    http://cheapchinajordans.confaccess.com/

  6. %>

    プルミエール シャネル said 07/03/2013 at 13h54 later:

    だからヲタクがどんどん離れていってるんだろうね

  7. %>

    weislessiot said 08/03/2013 at 03h10 later:

    Superb Post.thanks for share..even more wait ..

    christian louboutin shoes

  8. %>

    unsaranny said 09/03/2013 at 04h33 later:

    An fascinating discussion is worth comment. I think that you simply should really write even more on this topic, it might not be a taboo subject but frequently persons are not enough to speak on such topics. To the next. Cheers

    jordan shoes

  9. %>

    ChristianLouboutinFo said 10/03/2013 at 15h54 later:

    just go. man shoes size 6.5 are so great & I remain so fashion.. I like man shoes size 6.5 :) Christian Louboutin For Men http://www.cheapchristianlouboutinman.com/

  10. %>

    FedeNigeeduct said 11/03/2013 at 04h31 later:

    fairly nice post, i surely enjoy this webpage, keep on it

    cheap nfl jerseys

    http://nfljerseys2012.joomla-host.org

  11. %>

    FedeNigeeduct said 11/03/2013 at 14h37 later:

    You’ll find some intriguing points in time in this article but I do not know if I see all of them center to heart. There is certainly some validity but I will take hold opinion until I look into it further. Superb write-up , thanks and we want much more! Added to FeedBurner at the same time

    Wholesale NFL Jerseys

    http://cheapchinajordans.humorme.info/

  12. %>

    FedeNigeeduct said 12/03/2013 at 01h26 later:

    very nice post, i surely enjoy this web site, maintain on it

    cheap jordans

    http://cheapchinajordans.66ghz.com/

  13. %>

    Chealinnahype said 12/03/2013 at 08h11 later:

    Youre so cool! I dont suppose Ive read something like this just before. So nice to come across somebody with some original thoughts on this subject. realy thank you for beginning this up. this web site is something that’s necessary on the internet, somebody with a small originality. beneficial job for bringing something new to the internet!

    jordans on sale

    http://buynfljerseysgo.22web.org/

  14. %>

    FedeNigeeduct said 12/03/2013 at 10h03 later:

    I’m commonly to blogging and i actually appreciate your content. The article has truly peaks my interest. I’m going to bookmark your web-site and keep checking for new information.

    nfl jerseys

    http://cheapchinajordans.ganadoyucatan.com

  15. %>

    Suigueacunc said 13/03/2013 at 03h38 later:

    This definitely answered my predicament, thank you!

    jordan 13

  16. %>

    FedeNigeeduct said 13/03/2013 at 12h02 later:

    I am regularly to blogging and i certainly appreciate your content. The article has seriously peaks my interest. I’m going to bookmark your website and maintain checking for new data.

    cheap jordans

    http://nfljerseys2012.mydiscussion.net

  17. %>

    Chealinnahype said 13/03/2013 at 16h41 later:

    you’ve got an excellent blog here! would you like to make some invite posts on my weblog?

    nfl kids jerseys

    http://cheapchinajordans.22web.org/

  18. %>

    Chealinnahype said 14/03/2013 at 00h58 later:

    Your place is valueble for me. Thanks!

    cheap air jordans

    http://buynfljerseysgo.a0001.net/

  19. %>

    Chealinnahype said 14/03/2013 at 03h21 later:

    This certainly answered my predicament, thank you!

    jordans on sale

    http://nfljerseys2012.my-board.org

  20. %>

    weislessiot said 14/03/2013 at 17h54 later:

    This is the suitable blog for everyone who wants to discover about this subject. You comprehend so much its just about tough to argue with you (not that I basically would want?-HaHa). You surely put a brand new spin on a subject thats been written about for years. Good stuff, just good!

    michael kors bags

  21. %>

    Suigueacunc said 14/03/2013 at 23h36 later:

    This web internet site is definitely a walk-through for all of the info you wanted about this and didn’t know who to ask. Glimpse here, and you will certainly discover it.

    cheap air jordans

  22. %>

    FedeNigeeduct said 15/03/2013 at 02h37 later:

    This web internet site is actually a walk-through for all the information you wanted about this and didn’t know who to ask. Glimpse here, and you’ll undoubtedly discover it.

    cheap jordan shoes

    http://cheapchinajordans.0fees.net/

  23. %>

    FedeNigeeduct said 15/03/2013 at 12h19 later:

    I’d have to check with you here. Which is not something I commonly do! I take pleasure in reading a post that can make consumers believe. Also, thanks for allowing me to comment!

    nfl kids jerseys

    http://buynfljerseysgo.iblogger.org/

  24. %>

    Suigueacunc said 16/03/2013 at 05h45 later:

    you have an excellent weblog here! would you like to create some invite posts on my weblog?

    cheap sneakers

  25. %>

    FedeNigeeduct said 16/03/2013 at 08h38 later:

    The next time I read a blog, I hope that it doesnt disappoint me as significantly as this 1. I mean, I know it was my selection to read, but I really thought youd have something intriguing to say. All I hear is really a bunch of whining about some thing which you could fix when you werent too busy searching for attention.

    cheap jordans

    http://buynfljerseysgo.html-5.me/

  26. %>

    Uncoophonag said 16/03/2013 at 08h52 later:

    I discovered your weblog internet site on google and check a few of your early posts. Continue to maintain up the highly superb operate. I just further up your RSS feed to my MSN News Reader. Looking for forward to reading even more from you later on!

    nfl throwback jerseys

    http://cheapchinajordans.likesyou.org/

  27. %>

    weislessiot said 17/03/2013 at 15h29 later:

    Spot on with this write-up, I truly feel this web site wants far more consideration. I’ll probably be once again to read far more, thanks for that information.

    christian louboutin

  28. %>

    Chealinnahype said 17/03/2013 at 22h15 later:

    I’m impressed, I have to say. Seriously rarely do I encounter a weblog that is both educative and entertaining, and let me tell you, you’ve got hit the nail on the head. Your notion is outstanding; the concern is something that not enough individuals are speaking intelligently about. I’m pretty happy that I stumbled across this in my search for something relating to this.

    custom nfl jerseys

    http://cheapchinajordans.22web.org/

  29. %>

    FedeNigeeduct said 17/03/2013 at 23h27 later:

    I’m sometimes to blogging and i actually appreciate your content. The write-up has definitely peaks my interest. I am going to bookmark your web-site and maintain checking for new information and facts.

    cheapest jordans

    http://buynfljerseysgo.pointepestcontrol1.com

  30. %>

    FedeNigeeduct said 18/03/2013 at 05h26 later:

    An impressive share, I just given this onto a colleague who was doing a little analysis on this. And he in fact purchased me breakfast given that I located it for him.. smile. So let me reword that: Thnx for the treat! But yeah Thnkx for spending the time to talk about this, I really feel strongly about it and adore reading more on this subject. If probable, as you develop into expertise, would you mind updating your weblog with alot more details? It truly is extremely helpful for me. Major thumb up for this blog post!

    cheap jordans

    http://cheapchinajordans.nichesite.org/

  31. %>

    Chealinnahype said 18/03/2013 at 06h37 later:

    Spot on with this write-up, I truly believe this website needs much more consideration. I’ll most likely be once more to read much more, thanks for that information.

    cheap jordan shoes

    http://cheapchinajordans.social-networking.me/

  32. %>

    Uncoophonag said 18/03/2013 at 07h08 later:

    There’s noticeably a bundle to understand about this. I assume you made particular nice points in features also.

    nfl authentic jerseys

    http://buynfljerseysgo.catpaint.net

  33. %>

    unsaranny said 18/03/2013 at 07h42 later:

    You will find some fascinating points in time in this write-up but I do not know if I see all of them center to heart. There is some validity but I will take hold opinion until I appear into it further. Superb post , thanks and we want alot more! Added to FeedBurner as well

    red soled shoes

  34. %>

    Uncoophonag said 18/03/2013 at 15h56 later:

    You’ll find certainly lots of details like that to take into consideration. That is an excellent point to bring up. I offer you the thoughts above as general inspiration but clearly you can find questions like the 1 you bring up where probably the most necessary factor will likely be working in honest fantastic faith. I don?t know if most effective practices have emerged around things like that, but I am positive that your job is clearly identified as a fair game. Both boys and girls feel the impact of just a moment’s pleasure, for the rest of their lives.

    lv bags

    http://cheapchinajordans.confaccess.com/

  35. %>

    Jeanynfy said 20/03/2013 at 14h20 later:

    “ I mean?” red bottom shoes for cheap why, since God created a good start … red bottoms shoes don’t scream friend stabbed you several times, so, today it is no longer news, in the “ when brother brother long short, something you who tube ” age, a true friend like reaching for the stars, had to lick a new injury, looked at the old scar, lament a: within the four seas without a friend. Christian Louboutin Boots

  36. %>

    windows 7 anytime upgrade key said 21/03/2013 at 03h50 later:

    miriam ist echt so scharf und blond einfach super diese frau

No trackbacks

Comments are disabled

Toxic Elephant is Matijs van Zuijlen's weblog.

Powered

Categories