Does &method(:foo) get inlined? Can it? Should it?

133 views
Skip to first unread message

Jörg W Mittag

unread,
Aug 7, 2011, 10:21:42 PM8/7/11
to rubini...@googlegroups.com
Hi.

I am a big fan of programming in point-free style, although
unfortunately Ruby makes that unnecessarily ugly. I.e., I very much
prefer

ary.each(&method(:puts))

over

ary.each {|el| puts el }

The reason for this is the old saying by Phil Karlton:

| There are only two hard problems in computer science. Cache invalidation and naming things.

If naming things is hard (i.e. expensive), then names shouldn't be
wasted on irrelevant things. And conversely, if something has a name,
then it is important.

The whole *point* of higher-level iteration methods like
Enumerable#each and friends is to lift collection operations over the
individual elements, IOW to make the individual elements not
important; ergo, the individual elements shouldn't need to be named.

However, today there was a StackOverflow question about the efficiency
of such point-free code, especially with regards to reified Method and
Proc objects.

Personally, I don't care. I have yet to see Object#method or
Method#to_proc even show up in any profile.

My first reaction was basically that any halfway decent Ruby execution
engine should be able to inline and optimize the point-free version
all the way back till it generates basically the same machine code as
the explicit one. However, I am now having second thoughts about
whether there are some aspects of the semantics of Method and Proc
objects that make it impossible for them to be as efficient as a
method call (which after speculative inlining typically ends up as
just a conditional jump).

Since Rubinius seems to be the most advanced and most aggressively
optimizing Ruby execution engine, I thought I'd ask here:

1. Does Rubinius currently optimize such point-free code?
2. If it doesn't, could it?
3. If it could, should it?

Thanks in advance!

Greetings,
jwm

Rich Morin

unread,
Aug 8, 2011, 1:06:31 PM8/8/11
to rubini...@googlegroups.com
Although I understand your rationale for point-free style,
I should note that it will seem _really peculiar_ to many
Rubyists. It might also cause maintenance issues, if the
maintainer doesn't understand the idiom.

This may not be a show-stopper, particularly if your code
isn't read or modified by others. However, you should keep
it in mind for any distributed or shared code .

-r
--
http://www.cfcl.com/rdm Rich Morin
http://www.cfcl.com/rdm/resume r...@cfcl.com
http://www.cfcl.com/rdm/weblog +1 650-873-7841

Software system design, development, and documentation

Evan Phoenix

unread,
Aug 8, 2011, 5:09:24 PM8/8/11
to rubini...@googlegroups.com
I think that using this style is certainly possible, but fairly obtuse to most rubyists. If you never wrote blocks and instead only wrote these &method(:blah) isms, the other programmers on your team would get frustrated with you.

That being said, you asked a technical question rather than a stylistic one, so I'll answer it technically.

You're assumption that it could be the same as a block is, I'm sad to say, dead wrong. There reason you don't see Method#to_proc and such in profiling is 2 fold:

1) Most (all?) MRI profilers do not show a methods that MRI defines in C, so they'd never show up.

2) The mechanism for activating a method that has been turned into a Proc is all in C, so the overhead is invisible on the invocation side too.

You're point about the arty differences are right on. Additionally, you're thinking that a VM could easily optimize it into a block is quite wrong. Object#method is a not specially, not something that would be detected and optimized away. Additionally, even with runtime optimizations, something like escape analysis is still required since #method returns a Method object that you'd have to see inside and extract the information from. On the invocation side, the invoked method can only do something special with the block in the case of block inlining, an optimization that only Rubinius has.

So to get to your questions:

1. Does Rubinius optimize this code? No. Could it? Yes, but it's hardly easy.
2. In time it could, yes.
3. In time it should, yes.

- Evan

--
Evan Phoenix // ev...@fallingsnow.net


On Monday, August 8, 2011 at 10:06 AM, Rich Morin wrote:

> Although I understand your rationale for point-free style,
> I should note that it will seem _really peculiar_ to many
> Rubyists. It might also cause maintenance issues, if the
> maintainer doesn't understand the idiom.
>
> This may not be a show-stopper, particularly if your code
> isn't read or modified by others. However, you should keep
> it in mind for any distributed or shared code .
>
> -r
> --
> http://www.cfcl.com/rdm Rich Morin

> http://www.cfcl.com/rdm/resume r...@cfcl.com (mailto:r...@cfcl.com)


> http://www.cfcl.com/rdm/weblog +1 650-873-7841
>
> Software system design, development, and documentation
>

> --
> --- !ruby/object:MailingList
> name: rubinius-dev
> view: http://groups.google.com/group/rubinius-dev?hl=en
> post: rubini...@googlegroups.com (mailto:rubini...@googlegroups.com)
> unsubscribe: rubinius-dev...@googlegroups.com (mailto:rubinius-dev...@googlegroups.com)


Reply all
Reply to author
Forward
0 new messages