Skip to content

Instantly share code, notes, and snippets.

@patshaughnessy
Created July 13, 2012 15:50
Show Gist options
  • Save patshaughnessy/3105631 to your computer and use it in GitHub Desktop.
Save patshaughnessy/3105631 to your computer and use it in GitHub Desktop.
Why is for faster than each on Ruby 1.8.7?

Great question! It turns out that in Ruby 1.9 or 2.0 it's actually faster to use each, and not for (by a similar very small amount).

Looking into why for is faster than each in Ruby 1.8.7, it turns out Ruby 1.8.7 uses a slightly different code path for each vs. for, although for still is automatically evaluated as a call to each internally:

if (nd_type(node) == NODE_ITER) {
  result = rb_eval(self, node->nd_iter);
}
else {
  VALUE recv;

  _block.flags &= ~BLOCK_D_SCOPE;
  BEGIN_CALLARGS;
  recv = rb_eval(self, node->nd_iter);
  END_CALLARGS;
  ruby_current_node = node;
  SET_CURRENT_SOURCE();
  result = rb_call(CLASS_OF(recv),recv,each,0,0,0,self);
}

I'm not 100% sure why each is slower - the first NODE_ITER case in the C code above - but I suspect because it's that using each requires using an additional AST node (NODE_CALL) while using for does not… the "each" call is made implicitly without having an AST node for it (the else code above).

Really interesting stuff…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment