* [ruby-core:93337] [Ruby trunk Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
@ 2019-06-24 17:49 ` nelhage
2019-06-28 10:25 ` [ruby-core:93405] " eregontp
` (8 subsequent siblings)
9 siblings, 0 replies; 10+ messages in thread
From: nelhage @ 2019-06-24 17:49 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been reported by nelhage (Nelson Elhage).
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:93405] [Ruby trunk Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
2019-06-24 17:49 ` [ruby-core:93337] [Ruby trunk Feature#15955] UnboundMethod#apply nelhage
@ 2019-06-28 10:25 ` eregontp
2019-07-25 21:01 ` [ruby-core:93916] [Ruby master " nelhage
` (7 subsequent siblings)
9 siblings, 0 replies; 10+ messages in thread
From: eregontp @ 2019-06-28 10:25 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by Eregon (Benoit Daloze).
Escape analysis might be able to remove the Method allocation of `unbound.bind(recv).call(*args)`.
In fact, TruffleRuby does it for such a pattern.
So the interesting question for me is whether this should be fixed by the JIT or by a new method.
Could you share a benchmark representing your usage?
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-78947
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:93916] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
2019-06-24 17:49 ` [ruby-core:93337] [Ruby trunk Feature#15955] UnboundMethod#apply nelhage
2019-06-28 10:25 ` [ruby-core:93405] " eregontp
@ 2019-07-25 21:01 ` nelhage
2019-07-26 13:48 ` [ruby-core:93933] " jean.boussier
` (6 subsequent siblings)
9 siblings, 0 replies; 10+ messages in thread
From: nelhage @ 2019-07-25 21:01 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by nelhage (Nelson Elhage).
Whoops, sorry for the belated response -- Redmine email seems to not be working for me. We have a `replace_method` helper that is a shorthand for doing something like:
```
orig_require = Kernel.instance_method(:require)
Kernel.define_method(:require) do |*args|
# … do some pre-processing
orig_require.bind(self).call(*args)
end
```
We use it in a number of places, including to replace `require` as part of our custom autoloader (c.f. this talk: https://www.youtube.com/watch?v=lKMOETQAdzs)
I'm not quite sure how to get a representative microbenchmark; I am sure I could construct ones where the overhead is anywhere from ~0% to arbitrarily high. Profiling shows that as much as ~6% of the allocation on app startup comes from `UnboundMethod#bind` calls.
There are also other places I'd like to use this idiom. We had an incident the other day related to Sorbet's [use of `is_a?`](https://github.com/sorbet/sorbet/blob/d12b7144d2222398e0f28a772b7759fe26b2b9ba/gems/sorbet-runtime/lib/types/types/simple.rb#L20) (a `BasicObject` subtype that was being passed around had a surprising `is_a?` implementation) in runtime checking.
I'd love to be able to grab `Object.instance_method(:is_a?)` and then use that in our typechecking to make sure that we can test true subtyping no matter what monkey-patches are in place, but we know from past work that adding even a single allocation to the common case of runtime typechecking is too expensive.
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-80042
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:93933] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
` (2 preceding siblings ...)
2019-07-25 21:01 ` [ruby-core:93916] [Ruby master " nelhage
@ 2019-07-26 13:48 ` jean.boussier
2019-07-26 18:47 ` [ruby-core:93936] " eregontp
` (5 subsequent siblings)
9 siblings, 0 replies; 10+ messages in thread
From: jean.boussier @ 2019-07-26 13:48 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by byroot (Jean Boussier).
Zeitwerk had the exact same use case recently: https://github.com/fxn/zeitwerk/blob/ba7ff65d40a4309701981f9443249ac7e0e8c65f/lib/zeitwerk/real_mod_name.rb
i.e. get the true Module name even if the method was redefined.
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-80062
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:93936] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
` (3 preceding siblings ...)
2019-07-26 13:48 ` [ruby-core:93933] " jean.boussier
@ 2019-07-26 18:47 ` eregontp
2019-07-30 8:13 ` [ruby-core:94040] " ko1
` (4 subsequent siblings)
9 siblings, 0 replies; 10+ messages in thread
From: eregontp @ 2019-07-26 18:47 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by Eregon (Benoit Daloze).
I think this makes sense for convenience and better performance on MRI or during interpretation (vs in compiled code).
Using an UnboundMethod for getting a copy of a method at a given time is indeed a good usage, we use it in TruffleRuby quite a bit.
For the specific case of `is_a?`, may I recommend using `Module#===`?
That's much less often overridden, and it works for BasicObject (#is_a? is only defined in Kernel, so not for BasicObject).
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-80098
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:94040] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
` (4 preceding siblings ...)
2019-07-26 18:47 ` [ruby-core:93936] " eregontp
@ 2019-07-30 8:13 ` ko1
2019-08-13 21:27 ` [ruby-core:94329] " ruby-lang-bugs
` (3 subsequent siblings)
9 siblings, 0 replies; 10+ messages in thread
From: ko1 @ 2019-07-30 8:13 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by ko1 (Koichi Sasada).
> In fact, TruffleRuby does it for such a pattern.
I wonder that people use this pattern! (I'd never used it except test).
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-80265
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:94329] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
` (5 preceding siblings ...)
2019-07-30 8:13 ` [ruby-core:94040] " ko1
@ 2019-08-13 21:27 ` ruby-lang-bugs
2019-08-23 2:40 ` [ruby-core:94493] " mame
` (2 subsequent siblings)
9 siblings, 0 replies; 10+ messages in thread
From: ruby-lang-bugs @ 2019-08-13 21:27 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by darkdimius (Dmitry Petrashko).
> I wonder that people use this pattern! (I'd never used it except test).
This pattern currently represents substantial fraction of allocations that Sorbet runtime does, so building a way to not allocate in this pattern might have a sizeable impact in reducing the overhead of runtime type checking.
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-80717
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:94493] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
` (6 preceding siblings ...)
2019-08-13 21:27 ` [ruby-core:94329] " ruby-lang-bugs
@ 2019-08-23 2:40 ` mame
2019-08-23 3:28 ` [ruby-core:94495] " mame
2019-08-30 0:05 ` [ruby-core:94673] " mame
9 siblings, 0 replies; 10+ messages in thread
From: mame @ 2019-08-23 2:40 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by mame (Yusuke Endoh).
File umethod_apply.patch added
Hi @nelhage and @darkdimius :-)
I'm attaching a patch for `UnboundMethod#apply(obj, *args, &blk)` as a shortcut to `.bind(obj).call(*args, &blk)` without allocation of a Method object.
I have heard the same situation as Sorbet for `pp`. `pp` calls `method` method against its arguments. The intention is to call `Object#method`, but sometimes it is overridden with completely different behavior, e.g., `Net::HTTPGenericRequest#method`. So `pp` is using the same hack: https://github.com/ruby/ruby/blob/master/lib/pp.rb#L92
So I agree with the proposal. I'm unsure if the name `apply` is good or not. I'd like to ask matz at the next dev-meeting.
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-80928
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
---Files--------------------------------
umethod_apply.patch (5.01 KB)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:94495] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
` (7 preceding siblings ...)
2019-08-23 2:40 ` [ruby-core:94493] " mame
@ 2019-08-23 3:28 ` mame
2019-08-30 0:05 ` [ruby-core:94673] " mame
9 siblings, 0 replies; 10+ messages in thread
From: mame @ 2019-08-23 3:28 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by mame (Yusuke Endoh).
Here is a benchmark:
```
class Foo
def foo
end
end
meth = Foo.instance_method(:foo)
obj = Foo.new
10000000.times { meth.bind(obj).call } # 1.84 sec
10000000.times { meth.apply(obj) } # 1.04 sec
```
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-80930
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
---Files--------------------------------
umethod_apply.patch (5.01 KB)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ruby-core:94673] [Ruby master Feature#15955] UnboundMethod#apply
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
` (8 preceding siblings ...)
2019-08-23 3:28 ` [ruby-core:94495] " mame
@ 2019-08-30 0:05 ` mame
9 siblings, 0 replies; 10+ messages in thread
From: mame @ 2019-08-30 0:05 UTC (permalink / raw)
To: ruby-core
Issue #15955 has been updated by mame (Yusuke Endoh).
Matz approved the feature. The name "apply" was arguable in some terms:
* We may want to use the name "apply" for other purpose in future.
* This API will be used not so frequently. Only some fundamental libraries (like pp, sorbet-runtime, zeitwerk, etc.) will use it.
I proposed `UnboundMethod#bind_call` at the developers' meeting, and matz liked it. I'll commit it soon.
----------------------------------------
Feature #15955: UnboundMethod#apply
https://bugs.ruby-lang.org/issues/15955#change-81278
* Author: nelhage (Nelson Elhage)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
I'd love a way to apply an UnboundMethod to a receiver and list of args without having to first `bind` it. I've ended up using `UnboundMethod`s in some hot paths in my application due to our metaprogramming idioms, and the allocation from `.bind` is comparatively expensive.
I'd love `unbound_method.apply(obj, args…)` to be equivalent to `unbound_method.bind(obj).call(args…)` but without allocating the intermediate `Method`
---Files--------------------------------
umethod_apply.patch (5.01 KB)
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-08-30 0:05 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <redmine.issue-15955.20190624174954@ruby-lang.org>
2019-06-24 17:49 ` [ruby-core:93337] [Ruby trunk Feature#15955] UnboundMethod#apply nelhage
2019-06-28 10:25 ` [ruby-core:93405] " eregontp
2019-07-25 21:01 ` [ruby-core:93916] [Ruby master " nelhage
2019-07-26 13:48 ` [ruby-core:93933] " jean.boussier
2019-07-26 18:47 ` [ruby-core:93936] " eregontp
2019-07-30 8:13 ` [ruby-core:94040] " ko1
2019-08-13 21:27 ` [ruby-core:94329] " ruby-lang-bugs
2019-08-23 2:40 ` [ruby-core:94493] " mame
2019-08-23 3:28 ` [ruby-core:94495] " mame
2019-08-30 0:05 ` [ruby-core:94673] " mame
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).