Re: Bytecode optimization

2009-03-15 Thread Christophe Grand

Howard Lewis Ship a écrit :
 I have to wonder a bit about the ability to optimize.  Everything
 boils down to one of the seven or so basic forms.  That's a lot of
 function calls to do even small things, like adding numbers. You might
 think that simple math would be optimized and inlined, but it isn't:

 Clojure
 user= (doc +)
 -
 clojure.core/+
 ([] [x] [x y] [x y  more])
   Returns the sum of nums. (+) returns 0.
 nil
 user= (ns clojure.core)
 #Namespace clojure.core
 clojure.core= (defn + [x y] (* x y))
 #'clojure.core/+
 clojure.core= (+ 3 5)
 15
 clojure.core=

 This implies, to me, that Clojure is doing a full functional call,
 with dynamic lookup via the namespace, even for +.  To me, this means
 that Clojure will never be as fast as Java code *when implementing the
 same algorithm*.  Clojure will be faster when taking advantage of
 laziness and concurrency and that's fine by me.
   

Not quite. + (and al.) gets special treatment, it is inlined:
clojure.core= (defn add [x y] (+ x y))
#'clojure.core/add
clojure.core= (defn + [x y] (* x y))
#'clojure.core/+
clojure.core= (+ 3 5)
15
clojure.core= (add 3 5)
8

This allows, in a tight loop, the jit to emit code as fast as equivalent 
java code.

Christophe


-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.blogspot.com/ (en)



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



Re: Bytecode optimization

2009-03-14 Thread Stu Hood
Rich has done a lot of work to make sure that when you are working with
primitives, the JVM bytecode ends up being very similar to what Java would
generate. See http://clojure.org/java_interop#toc36

Thanks,
Stu

On Thu, Mar 12, 2009 at 6:20 PM, Howard Lewis Ship hls...@gmail.com wrote:


 Well, at some point I'll open up the code and check.  Though I'll be
 overly tempted to write some comments, fix the indentation and write
 some tests if I do!

 On Thu, Mar 12, 2009 at 2:36 PM, Jarkko Oranen chous...@gmail.com wrote:
 
 
  On Mar 12, 11:15 pm, Howard Lewis Ship hls...@gmail.com wrote:
  I have to wonder a bit about the ability to optimize.  Everything
  boils down to one of the seven or so basic forms.  That's a lot of
  function calls to do even small things, like adding numbers. You might
  think that simple math would be optimized and inlined, but it isn't:
 
  Clojure
  user= (doc +)
  -
  clojure.core/+
  ([] [x] [x y] [x y  more])
Returns the sum of nums. (+) returns 0.
  nil
  user= (ns clojure.core)
  #Namespace clojure.core
  clojure.core= (defn + [x y] (* x y))
  #'clojure.core/+
  clojure.core= (+ 3 5)
  15
  clojure.core=
 
  This implies, to me, that Clojure is doing a full functional call,
  with dynamic lookup via the namespace, even for +.
 
  I think this is mistaken. Sure, for (+ foo bar) calls in the repl
  Clojure will do a full lookup,  but if you have  addition in a tight
  loop, the JVM should notice this and optimise it further. (I think
  Clojure also does some kind of caching.) You can also use type casts
  to make clojure use primitive instead of boxed math, bringing
  performance very close to Java.
 
  Now, it's probably true that the most straightforward Clojure
  implementation of an algorithm is likely not quite as fast as the Java
  equivalent, with a few tricks, you can often get pretty close.
 
  I don't have very in-depth knowledge of how Clojure handles these
  performance issues, but I believe your assumption is overly
  pessimistic. :)
 
  --
  Jarkko
  
 



 --
 Howard M. Lewis Ship

 Creator Apache Tapestry and Apache HiveMind

 


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



Bytecode optimization

2009-03-12 Thread Joshua Fox
I was just reading
thishttp://developer.amd.com/documentation/Articles/pages/01302008_jvm.aspx
and
wondering: Does Clojure's pure-functional design enhance VM-level bytecode
optimization by simplifying escape analysis?

Joshua

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



Re: Bytecode optimization

2009-03-12 Thread Stuart Sierra

On Mar 12, 4:46 am, Joshua Fox joshuat...@gmail.com wrote:
 wondering: Does Clojure's pure-functional design enhance VM-level bytecode
 optimization by simplifying escape analysis?

Functional design doesn't necessarily make bytecode easy to optimize.
But Rich Hickey works hard on making Clojure generate bytecode that
the JVM will optimize.

-Stuart Sierra
--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Re: Bytecode optimization

2009-03-12 Thread Mark Addleman



On Mar 12, 10:56 am, Stuart Sierra the.stuart.sie...@gmail.com
wrote:
 On Mar 12, 4:46 am, Joshua Fox joshuat...@gmail.com wrote:

  wondering: Does Clojure's pure-functional design enhance VM-level bytecode
  optimization by simplifying escape analysis?

 Functional design doesn't necessarily make bytecode easy to optimize.
 But Rich Hickey works hard on making Clojure generate bytecode that
 the JVM will optimize.

Agreed, but in the particular case of Escape Analysis, a functional
language has better than a fighting chance of generating easily
optimized bytecode.  The real problem is that JVMs do not yet allocate
non-escaping objects on the stack.
--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Re: Bytecode optimization

2009-03-12 Thread Howard Lewis Ship

I have to wonder a bit about the ability to optimize.  Everything
boils down to one of the seven or so basic forms.  That's a lot of
function calls to do even small things, like adding numbers. You might
think that simple math would be optimized and inlined, but it isn't:

Clojure
user= (doc +)
-
clojure.core/+
([] [x] [x y] [x y  more])
  Returns the sum of nums. (+) returns 0.
nil
user= (ns clojure.core)
#Namespace clojure.core
clojure.core= (defn + [x y] (* x y))
#'clojure.core/+
clojure.core= (+ 3 5)
15
clojure.core=

This implies, to me, that Clojure is doing a full functional call,
with dynamic lookup via the namespace, even for +.  To me, this means
that Clojure will never be as fast as Java code *when implementing the
same algorithm*.  Clojure will be faster when taking advantage of
laziness and concurrency and that's fine by me.

I would bet Clojure is top tier, perhaps even fastest, among dynamic
languages for the JVM because of the superior Java  interop,
especially when you help it out by defining symbol types (so it can
generate type appropriate method calls, rather than using reflective
access).


On Thu, Mar 12, 2009 at 12:00 PM, Mark Addleman
mark_addle...@bigfoot.com wrote:



 On Mar 12, 10:56 am, Stuart Sierra the.stuart.sie...@gmail.com
 wrote:
 On Mar 12, 4:46 am, Joshua Fox joshuat...@gmail.com wrote:

  wondering: Does Clojure's pure-functional design enhance VM-level bytecode
  optimization by simplifying escape analysis?

 Functional design doesn't necessarily make bytecode easy to optimize.
 But Rich Hickey works hard on making Clojure generate bytecode that
 the JVM will optimize.

 Agreed, but in the particular case of Escape Analysis, a functional
 language has better than a fighting chance of generating easily
 optimized bytecode.  The real problem is that JVMs do not yet allocate
 non-escaping objects on the stack.
 




-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

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



Re: Bytecode optimization

2009-03-12 Thread Jarkko Oranen


On Mar 12, 11:15 pm, Howard Lewis Ship hls...@gmail.com wrote:
 I have to wonder a bit about the ability to optimize.  Everything
 boils down to one of the seven or so basic forms.  That's a lot of
 function calls to do even small things, like adding numbers. You might
 think that simple math would be optimized and inlined, but it isn't:

 Clojure
 user= (doc +)
 -
 clojure.core/+
 ([] [x] [x y] [x y  more])
   Returns the sum of nums. (+) returns 0.
 nil
 user= (ns clojure.core)
 #Namespace clojure.core
 clojure.core= (defn + [x y] (* x y))
 #'clojure.core/+
 clojure.core= (+ 3 5)
 15
 clojure.core=

 This implies, to me, that Clojure is doing a full functional call,
 with dynamic lookup via the namespace, even for +.

I think this is mistaken. Sure, for (+ foo bar) calls in the repl
Clojure will do a full lookup,  but if you have  addition in a tight
loop, the JVM should notice this and optimise it further. (I think
Clojure also does some kind of caching.) You can also use type casts
to make clojure use primitive instead of boxed math, bringing
performance very close to Java.

Now, it's probably true that the most straightforward Clojure
implementation of an algorithm is likely not quite as fast as the Java
equivalent, with a few tricks, you can often get pretty close.

I don't have very in-depth knowledge of how Clojure handles these
performance issues, but I believe your assumption is overly
pessimistic. :)

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



Re: Bytecode optimization

2009-03-12 Thread Howard Lewis Ship

Well, at some point I'll open up the code and check.  Though I'll be
overly tempted to write some comments, fix the indentation and write
some tests if I do!

On Thu, Mar 12, 2009 at 2:36 PM, Jarkko Oranen chous...@gmail.com wrote:


 On Mar 12, 11:15 pm, Howard Lewis Ship hls...@gmail.com wrote:
 I have to wonder a bit about the ability to optimize.  Everything
 boils down to one of the seven or so basic forms.  That's a lot of
 function calls to do even small things, like adding numbers. You might
 think that simple math would be optimized and inlined, but it isn't:

 Clojure
 user= (doc +)
 -
 clojure.core/+
 ([] [x] [x y] [x y  more])
   Returns the sum of nums. (+) returns 0.
 nil
 user= (ns clojure.core)
 #Namespace clojure.core
 clojure.core= (defn + [x y] (* x y))
 #'clojure.core/+
 clojure.core= (+ 3 5)
 15
 clojure.core=

 This implies, to me, that Clojure is doing a full functional call,
 with dynamic lookup via the namespace, even for +.

 I think this is mistaken. Sure, for (+ foo bar) calls in the repl
 Clojure will do a full lookup,  but if you have  addition in a tight
 loop, the JVM should notice this and optimise it further. (I think
 Clojure also does some kind of caching.) You can also use type casts
 to make clojure use primitive instead of boxed math, bringing
 performance very close to Java.

 Now, it's probably true that the most straightforward Clojure
 implementation of an algorithm is likely not quite as fast as the Java
 equivalent, with a few tricks, you can often get pretty close.

 I don't have very in-depth knowledge of how Clojure handles these
 performance issues, but I believe your assumption is overly
 pessimistic. :)

 --
 Jarkko
 




-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

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