Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-20 Thread Nathan Marz
Thanks. It doesn't currently use type hints to distinguish between multiple 
methods of the same arity. Opened an issue: 
https://github.com/redplanetlabs/proxy-plus/issues/1

On Monday, January 20, 2020 at 11:57:31 AM UTC-5, Ghadi Shayban wrote:
>
> I tried using proxy+ for one of the proxy implementations in clojure.core, 
> but I ran into an issue where a "too many matching methods" got thrown at 
> macroexpansion time. The proxy I tried to replicate was PrintWriter-on 
> .
>  
> The exception-data contained two "write" methods that matched arity but 
> didn't match param types. Repro below.
>
> (require '[com.rpl.proxy-plus :refer [proxy+]]))
>
> (defn ^java.io.PrintWriter proxy+test
>   [flush-fn close-fn]
>   (let [sb (StringBuilder.)]
> (-> (proxy+ []
>   java.io.Writer
>   (flush [this]
>  (when (pos? (.length sb))
>(flush-fn (.toString sb)))
>  (.setLength sb 0))
>   (close [this]
>  (.flush this)
>  (when close-fn (close-fn))
>  nil)
>   (write [this ^chars str-cbuf off len]
>  (when (pos? len)
>(.append sb str-cbuf ^int off ^int len
> java.io.BufferedWriter.
> java.io.PrintWriter.)))
>
> On Monday, January 13, 2020 at 11:47:06 AM UTC-5, Nathan Marz 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 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/aae86211-1bc6-41db-9122-291b48f81a18%40googlegroups.com.


Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-20 Thread Ghadi Shayban
I tried using proxy+ for one of the proxy implementations in clojure.core, 
but I ran into an issue where a "too many matching methods" got thrown at 
macroexpansion time. The proxy I tried to replicate was PrintWriter-on 
.
 
The exception-data contained two "write" methods that matched arity but 
didn't match param types. Repro below.

(require '[com.rpl.proxy-plus :refer [proxy+]]))

(defn ^java.io.PrintWriter proxy+test
  [flush-fn close-fn]
  (let [sb (StringBuilder.)]
(-> (proxy+ []
  java.io.Writer
  (flush [this]
 (when (pos? (.length sb))
   (flush-fn (.toString sb)))
 (.setLength sb 0))
  (close [this]
 (.flush this)
 (when close-fn (close-fn))
 nil)
  (write [this ^chars str-cbuf off len]
 (when (pos? len)
   (.append sb str-cbuf ^int off ^int len
java.io.BufferedWriter.
java.io.PrintWriter.)))

On Monday, January 13, 2020 at 11:47:06 AM UTC-5, Nathan Marz 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 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/bfd8e45a-4843-4422-b47f-3303ce53364e%40googlegroups.com.


Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-15 Thread Mike Rodriguez
Ah yes. I didn't consider that.

On Wednesday, January 15, 2020 at 12:31:13 PM UTC-5, Alex Miller wrote:
>
> Using vars lets you iterate on the impl functions without invalidating the 
> proxy instances. I'm not sure if that was the reason, but that would be one 
> advantage.
>
> On Wednesday, January 15, 2020 at 10:46:36 AM UTC-6, Mike Rodriguez wrote:
>>
>> Do you have any idea about the reason that the Clojure implementation was 
>> done this way - when it obviously seems a bit limited and also slower than 
>> necessary? Just curious if there's some historical context.
>>
>> On Tuesday, January 14, 2020 at 11:58:17 AM UTC-5, Nathan Marz wrote:
>>>
>>> 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  [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  
>> 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 
>>> 

Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-15 Thread Alex Miller
Using vars lets you iterate on the impl functions without invalidating the 
proxy instances. I'm not sure if that was the reason, but that would be one 
advantage.

On Wednesday, January 15, 2020 at 10:46:36 AM UTC-6, Mike Rodriguez wrote:
>
> Do you have any idea about the reason that the Clojure implementation was 
> done this way - when it obviously seems a bit limited and also slower than 
> necessary? Just curious if there's some historical context.
>
> On Tuesday, January 14, 2020 at 11:58:17 AM UTC-5, Nathan Marz wrote:
>>
>> 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  [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  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
>>  
>> 
>> .
>>
>

-- 
You received this 

Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-15 Thread Mike Rodriguez
Do you have any idea about the reason that the Clojure implementation was 
done this way - when it obviously seems a bit limited and also slower than 
necessary? Just curious if there's some historical context.

On Tuesday, January 14, 2020 at 11:58:17 AM UTC-5, Nathan Marz wrote:
>
> 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  [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  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
>  
> 
> .
>


-- 
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

Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-14 Thread Brent Millare
Thanks this is wonderful! Nice work

On Tuesday, January 14, 2020 at 11:58:17 AM UTC-5, Nathan Marz wrote:
>
> 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  [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  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
>  
> 
> .
>


-- 
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, 

Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-14 Thread Nathan Marz
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  [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  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
  
 
 .

>>>

-- 
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.


Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-14 Thread Brent Millare
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  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
>>>  
>>> 
>>> .
>>>
>>

-- 
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/1fdbb59a-73b5-4a79-94b1-6769578fe019%40googlegroups.com.


Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-13 Thread Nathan Marz
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  > 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
>>  
>> 
>> .
>>
>

-- 
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/a39e0803-2a07-447c-ba8b-7c47f243d83b%40googlegroups.com.


Re: [ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-13 Thread John Newman
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  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 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/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com
> 
> .
>

-- 
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/CAFw7CQJo8fGyqsbpW1YTPT0t10ckiTDkR4%3DN-NL%2B9uR1e1t17A%40mail.gmail.com.


[ANN] proxy-plus: Faster and more usable replacement for "proxy"

2020-01-13 Thread Nathan Marz
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 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/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com.