Let's start with wtf!?

Posted by pratik
on Saturday, June 30

UPDATE : Check Ticket 8818

Welcome to my new blog :) Now over to rails..

So you’ve been told about using cute shortcuts for enumerator like Post.find(:all).map(&:title) – you feel great using it, don’t you ?? And you laughed at those who didn’t understand how &:sym worked and continued to use .map ( |shit| shit.stupid } syntaxt! You were made feel geeky indirectly. I was there :-)

But those days are “over” and it’s time to go back home!

I’d let benchmark speak for me..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
require 'benchmark'

class Symbol
  def to_proc
    Proc.new { |*args| args.shift.__send__(self, *args) }
  end
end

n = 10000

s = Struct.new :id
messages = []
n.times { messages << s.new(:id => rand(n)) }

Benchmark.bm do |x|  
  # Integer
  x.report { n.times { messages.map{|m| m.id} } }
  x.report { n.times { messages.map(&:id) } }
end

# $ ruby perform.rb 
#       user     system      total        real
#  33.280000   0.860000  34.140000 ( 34.912584)
# 191.940000   1.660000 193.600000 (197.168849)

Need I say anymore ? Wake up and smell the coffee.

Related ticket

Comments

Leave a response

  1. ara.t.howardJune 30, 2007 @ 07:58 AM

    of course my bloody formatting got eaten.. round two:

    cfp:~ > cat a.rb require ‘benchmark’

    class Symbol def to_proc lambda{|obj| obj.send self} end end

    n = 10000

    s = Struct.new :id messages = [] n.times { messages << s.new(:id => rand(n)) }

    Benchmark.bm do |x|
    # Integer x.report { n.times { messages.map{|m| m.id} } } x.report { n.times { messages.map(&:id) } } end

    cfp:~ > ruby a.rb user system total real 31.160000 1.200000 32.360000 ( 33.135435) 40.640000 1.380000 42.020000 ( 43.270193)

  2. PratikJune 30, 2007 @ 02:26 PM

    Ara,

    Thanks a lot ! I’ve submitted a new ticket using your suggestion.

    Let’s hope it make it to rails and we all can get back &:to :-)

  3. PratikJune 30, 2007 @ 02:51 PM

    Of course monkey patching a monkey patch is not allowed here ;-)

  4. K. Adam ChristensenJuly 01, 2007 @ 01:41 AM

    Nice test and more-over, good patch.

    I know that Symbol#to_proc is supposed to be implemented in ruby 1.9 and now I’m curious if 1.9 will have the same pitfall as rails did.

  5. Anil WadghuleJuly 01, 2007 @ 01:28 PM

    Nice snippet, I was not aware of difference between &: and normal {|m| m.id} block. I thought both are the same. I hope patch get accepted. Thanks Pratik.

  6. Sam SmootJuly 03, 2007 @ 04:02 AM

    I guess I never looked at how ActiveSupport implemented Symbol#to_proc. I’d always assumed it was pretty much what Ara posted.

    Anyone have any idea why it’s using var-args? I can’t think of a use-case for that (in this context) for the life of me.

  7. PratikJuly 03, 2007 @ 12:43 PM

    Sam,

    It lets you do things like [1,2,3].inject(&:+)

  8. Sam SmootJuly 03, 2007 @ 04:28 PM

    Pratik, thanks. Still, seems odd. Outside of a sum like this, other methods that pass multiple params to a block, the first being the object acted on, and also work with only RHS arguments to the method being sent… that’s pretty specific. How many can there be?

    Maybe this should be a Ruby Quiz. :)