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…