The speedup comes from proxy+ directly overriding methods with the provided
implementation, while Clojure's proxy has additional indirection. For
example, if you do (proxy [Object] [] (toString [] "hello")), the bytecode
for toString is:
public java.lang.String toString();
0 aload_0 [this]
1 getfield user.proxy$java.lang.Object$ff19274a.__clojureFnMap :
clojure.lang.IPersistentMap [16]
4 ldc <String "toString"> [52]
6 invokestatic clojure.lang.RT.get(java.lang.Object,
java.lang.Object) : java.lang.Object [36]
9 dup
10 ifnull 28
13 checkcast clojure.lang.IFn [38]
16 aload_0 [this]
17 invokeinterface clojure.lang.IFn.invoke(java.lang.Object) :
java.lang.Object [55] [nargs: 2]
22 checkcast java.lang.String [57]
25 goto 33
28 pop
29 aload_0 [this]
30 invokespecial java.lang.Object.toString() : java.lang.String [59]
33 areturn
Clojure keeps the implementations in a map, and for every dispatch it does
a map lookup by the method name. This is also why it can't handle
overriding the same method name with different arities.
For (proxy+ [] Object (toString [this] "hello")), the bytecode is:
public java.lang.String toString();
0 aload_0 [this]
1 getfield user.proxy_plus5358.toString5357 : clojure.lang.IFn [19]
4 aload_0 [this]
5 invokeinterface clojure.lang.IFn.invoke(java.lang.Object) :
java.lang.Object [30] [nargs: 2]
10 checkcast java.lang.String [32]
13 areturn
The implementation function is stored as a field, so the cost of dispatch
is a field get rather than a map lookup.
Clojure's proxy also overrides *every* available method in all
superclasses/interfaces, while proxy+ only overrides what you specify. So
proxy+ generates much smaller classes than proxy.
On Tuesday, January 14, 2020 at 10:30:32 AM UTC-5, Brent Millare wrote:
>
> I skimmed the code, I don't really understand how it makes it faster over
> proxy. Is it the generated ASM is better? What's the in-a-nutshell
> description of how it works?
>
> On Monday, January 13, 2020 at 1:28:46 PM UTC-5, Nathan Marz wrote:
>>
>> No differences in behavior except for API being like reify. It integrates
>> with AOT and can be consumed just like any other class. No idea how it
>> interacts with Graal.
>>
>> On Monday, January 13, 2020 at 12:29:35 PM UTC-5, John Newman wrote:
>>>
>>> Bravo 👏👏👏👏👏
>>>
>>> Are there any differences in behavior to be aware of? AOT, Graal,
>>> consuming proxy+ classes from vanilla clojure classes?
>>>
>>> On Mon, Jan 13, 2020, 11:47 AM Nathan Marz <[email protected]> wrote:
>>>
>>>> proxy+ is a replacement for Clojure's proxy that's faster and more
>>>> usable. proxy has a strange implementation where it overrides every
>>>> possible method and uses a mutable field to store a map of string ->
>>>> function for dispatching the methods. This causes it to be unable to
>>>> handle
>>>> methods with the same name but different arities.
>>>>
>>>> proxy+ fixes these issues with proxy. Usage is like reify, and it's up
>>>> to 10x faster.
>>>>
>>>> *Repository: *https://github.com/redplanetlabs/proxy-plus
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to [email protected]
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> [email protected]
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to [email protected].
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com
>>>>
>>>> <https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/clojure/6793548f-0bc9-4c10-8e5c-cf235aaaccce%40googlegroups.com.