Issue #12901 has been updated by Shyouhei Urabe.


Math Ieu wrote:
> Shyouhei Urabe wrote:
> > Math Ieu wrote:
> > > The introspection features like the "binding" method and maybe the way "eval" works might make this hard to optimize though (since they essentially capture everything?).
> > 
> > Yes.  This is why we capture everything.  And, you have to notice that binding and even evel itself are implemented as normal methods; they are subject to be aliased.  So you can't say if a Proc's binding is called or not until it is actually called (recap: ruby's method resolution is dynamic).  Never until you actually obtain its binding, a Proc's binding cannot be optimized because of possibility of being obtained later == you can't optimize at all.  This is where we stand.
> > 
> > I think it's impossible to optimize lambdas without breaking backwards compatibility.
> 
> But it could be enabled on-demand. Say with a magic comment, then all closures created from code of this file would be optimized to not capture everything. I guess there might as well be special syntax for it then though. Or maybe include something in the module with lambda/proc variants that don't capture everything.
> 
> Dunno if "lazy" capture could be a useful compromise? If binding/eval is ever called by/on a closure, then the rest of the variables from the stack is captured. It would only work if it's called before the corresponding levels of the stack unwind though (but full capture could be triggered beforehand if needed).

I (broadly) agree with you.  Extending or modifying the language to make optimization possible is a great idea.  Matz said in comment #9 that Koichi has one of such ideas.  Let us see what he proposes.

----------------------------------------
Feature #12901: Anonymous functions without scope lookup overhead
https://bugs.ruby-lang.org/issues/12901#change-63266

* Author: Richard Schneeman
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Right now if you are writing performance sensitive code you can get a performance bump by not using anonymous functions (procs, lambdas, blocks) due to the scope lookup overhead.

https://twitter.com/apotonick/status/791167782532493312?lang=en

I would like to be able to create an anonymous function and specify I don't need it to perform the lookup when called.

I am thinking that this code:

~~~
Proc.new(scope: false) {|var| puts var }
~~~

Would be the equivalent of 

~~~
def anon(var)
  puts var
end
~~~

If you call it while trying to access something from outside of the scope it would error

~~~
var = "hello"
Proc.new(scope: false) { puts var }.call
# => NameError: undefined local variable or method `var' for main:Object
~~~

An example of a case where this could be used is found in https://github.com/rails/sprockets/pull/417. In this case we are getting rid of anonymous functions in favor of a method created with refinements. This solution works but it was not an obvious optimization. It would be convenient to have a syntax for defining anonymous functions that do not need access to caller scope.






-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>