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 <natha...@gmail.com> 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 clo...@googlegroups.com >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> clo...@googlegroups.com >>>> 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 clo...@googlegroups.com. >>>> 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 clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com 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 clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/6793548f-0bc9-4c10-8e5c-cf235aaaccce%40googlegroups.com.