Clojure vs Java speed (was: Alternatives to C)

Discussion in 'Java' started by fft1976, Jul 29, 2009.

  1. fft1976

    fft1976 Guest

    On Jul 28, 9:46 pm, Oxide Scrubber <> wrote:

    > >> fft1976 wrote:
    > >>> Java: 1.5x slower than C as a rule of thumb.
    > >> I think it can achieve parity.

    >
    > > I disagree. I don't think the JIT can do much about the memory layout
    > > of the data structures. Compare a vector of complex numbers or of 3D
    > > vectors (NOT of pointers to them) in C/C++ and Java. Run some tests. I
    > > did and I looked at others'.

    >
    > > For me, 1.5x is a good trade-off for safety though.

    >
    > The JIT can't, but the coder can. If you want a vector of N
    > double-precision complex numbers in Java that is contiguous in memory,
    > for example, you could use a Java array of 2xN doubles and index into it
    > appropriately.


    This is fanboy fantasy, not reality. If I have a library for dealing
    with 3D vectors, I'm not going to lay out my data in flat arrays and
    copy the vectors back and forth. Also, this trick won't work with non-
    homogeneous records.

    > >> With Java, in most cases you can slap "implements Cloneable" on a
    > >> class and make the clone method public,

    >
    > > Java's "clone" does a shallow copy only (check the docs).

    >
    > True. If you want a deep copy you will have to implement it yourself.


    That's what I wrote. What was the point of your comment?


    > Or
    > you can make a deepCopy static utility method that exploits
    > "Serializable" to deep copy anything that's serializable simply by
    > serializing and deserializing it (which can use memory, or a temp file,
    > and not much memory if you make an auxiliary class implement both
    > InputStream and OutputStream, with its OutputStream methods writing to a
    > growable buffer and its InputStream methods consuming (possibly blocking
    > if necessary) from same. Closing the OutputStream aspect EOFs the
    > InputStream aspect. Then wrap in ObjectInput/OutputStream. You can use a
    > BlockingQueue of byte arrays of length 8192 (or whatever), serialize to
    > one end and deserialize from the other in concurrent threads, and it
    > will tend to not use much memory. Limit the BlockingQueue length to 1
    > item and it will never use much more than 8Kbyte (the OutputStream
    > aspect will block until the InputStream aspect consumes from the queue).


    Ouch...

    > If the bulk of the time is spent performing arithmetic operations on
    > just a few values,


    We are talking number crunching here, not useless pissing contests,
    like calculating the digits of Pi.

    > If the arithmetic is bignum, the bulk of your time will be spent
    > performing individual bignum operations.


    Contrary to what the term sounds like, number crunching is rarely
    about bignums.

    > If the arithmetic is on smallnums in arrays and the computations are
    > mostly mutations, then you may want to use Java arrays,


    That's what I said.

    > In practice,
    > Clojure access to Java arrays, even primitive arrays, seems to
    > be slow. This may be addressed in a future version.


    Yeah, yeah...

    I noticed that you decided to delete this, by the way:

    In practice, experts seem to
    agree that Clojure is 5-10 times slower than Java:

    http://groups.google.com/group/clojure/msg/92b33476c0507478

    (relevant follow-up set)
    fft1976, Jul 29, 2009
    #1
    1. Advertising

  2. fft1976

    SG Guest

    On 29 Jul., 07:55, fft1976 <> wrote:
    > On Jul 28, 9:46 pm, Oxide Scrubber <> wrote:
    >
    > > The JIT can't, but the coder can. If you want a vector of N
    > > double-precision complex numbers in Java that is contiguous in memory,
    > > for example, you could use a Java array of 2xN doubles and index into it
    > > appropriately.

    >
    > This is fanboy fantasy, not reality. If I have a library for dealing
    > with 3D vectors, I'm not going to lay out my data in flat arrays and
    > copy the vectors back and forth. Also, this trick won't work with non-
    > homogeneous records.


    Agreed. I can confirm that C++ is much better for my kind of number
    chrunching tasks. I have to solve big nonlinear optimization problems
    and switched from Java to C++ two years ago. I'm not looking back. The
    ability to write user-defined types that are handled like builtin
    types (no indirection, no heap allocations) combined with "true
    genericity" is key.

    > > In practice,
    > > Clojure access to Java arrays, even primitive arrays, seems to
    > > be slow. This may be addressed in a future version.


    Are we talking about the language "Clojure" (lisp dialect) or the
    cloSure proposal for Java 7?

    Cheers!
    SG
    SG, Jul 29, 2009
    #2
    1. Advertising

  3. Re: Clojure vs Java speed

    fft1976 failed for the second time to respect the Followup-To header:
    > On Jul 28, 9:46 pm, Oxide Scrubber <> wrote:
    >
    >>>> fft1976 wrote:
    >>>>> Java: 1.5x slower than C as a rule of thumb.
    >>>> I think it can achieve parity.
    >>> I disagree. I don't think the JIT can do much about the memory layout
    >>> of the data structures. Compare a vector of complex numbers or of 3D
    >>> vectors (NOT of pointers to them) in C/C++ and Java. Run some tests. I
    >>> did and I looked at others'.
    >>> For me, 1.5x is a good trade-off for safety though.

    >> The JIT can't, but the coder can. If you want a vector of N
    >> double-precision complex numbers in Java that is contiguous in memory,
    >> for example, you could use a Java array of 2xN doubles and index into it
    >> appropriately.

    >
    > This is fanboy fantasy, not reality.


    Stop attacking me. I have done nothing to deserve your repeated flamage.
    You must have the wrong target. Recheck and then go flame the correct
    target.

    > If I have a library for dealing with 3D vectors, I'm not going to lay
    > out my data in flat arrays and copy the vectors back and forth.


    If you have a library for dealing with X, in any language, you'll use
    the data as laid out by that library.

    A performant Java library for numerics should lay out its data in an
    appropriate manner so as to achieve performance, of course.

    > Also, this trick won't work with non-homogeneous records.


    It will work for records of a primitive type, such as double. It won't
    work if for some odd reason you want to mix ints and doubles in the same
    vector, no. In that unusual case you may be better off either using
    multiple separate arrays, but allocated one right after the other so
    probably close together, one with all the ints and one with all the
    doubles, or else resorting to JNI to implement some things.

    >>>> With Java, in most cases you can slap "implements Cloneable" on a
    >>>> class and make the clone method public,
    >>> Java's "clone" does a shallow copy only (check the docs).

    >> True. If you want a deep copy you will have to implement it yourself.

    >
    >> Or
    >> you can make a deepCopy static utility method that exploits
    >> "Serializable" to deep copy anything that's serializable simply by
    >> serializing and deserializing it (which can use memory, or a temp file,
    >> and not much memory if you make an auxiliary class implement both
    >> InputStream and OutputStream, with its OutputStream methods writing to a
    >> growable buffer and its InputStream methods consuming (possibly blocking
    >> if necessary) from same. Closing the OutputStream aspect EOFs the
    >> InputStream aspect. Then wrap in ObjectInput/OutputStream. You can use a
    >> BlockingQueue of byte arrays of length 8192 (or whatever), serialize to
    >> one end and deserialize from the other in concurrent threads, and it
    >> will tend to not use much memory. Limit the BlockingQueue length to 1
    >> item and it will never use much more than 8Kbyte (the OutputStream
    >> aspect will block until the InputStream aspect consumes from the queue).

    >
    > Ouch...


    No ouch. You'd only have to do this once, and then deepCopy would work
    on every serializable type in Java, including ones that didn't exist
    when you wrote deepCopy.

    >> If the bulk of the time is spent performing arithmetic operations on
    >> just a few values,

    >
    > We are talking number crunching here


    Yes, I know.

    >> If the arithmetic is bignum, the bulk of your time will be spent
    >> performing individual bignum operations.

    >
    > Contrary to what the term sounds like, number crunching is rarely
    > about bignums.


    I never said otherwise.

    >> If the arithmetic is on smallnums in arrays and the computations are
    >> mostly mutations, then you may want to use Java arrays,

    >
    > That's what I said.


    Now that the debate is over, please respect the followup-to header.

    It would have been better, of course, had you chose to end it *before*
    demonstrating to the entire world that you're unimaginative and
    ignorant. Ignorant of numerous performance tricks for Java and other JVM
    languages, ignorant of performant functional algorithms for various
    things, and ignorant of the actual facts from timing operations, which
    show all three languages capable of achieving the same top speed in
    numeric calculations. And unimaginative enough not only to be unable to
    think up any of these things, but also unable to think up arguments that
    aren't laced heavily with ad hominems and other rhetoric. "This is
    fanboy fantasy, not reality," "What was the point of your comment?,"
    "Ouch...," "We are talking number crunching here, not useless pissing
    contests," "Yeah, yeah...," and so forth do not constitute rational
    arguments.
    Oxide Scrubber, Jul 29, 2009
    #3
  4. Re: Clojure vs Java speed

    SG wrote:
    > On 29 Jul., 07:55, fft1976 <> wrote:
    >> On Jul 28, 9:46 pm, Oxide Scrubber <> wrote:
    >>> The JIT can't, but the coder can. If you want a vector of N
    >>> double-precision complex numbers in Java that is contiguous in memory,
    >>> for example, you could use a Java array of 2xN doubles and index into it
    >>> appropriately.

    >> This is fanboy fantasy, not reality. If I have a library for dealing
    >> with 3D vectors, I'm not going to lay out my data in flat arrays and
    >> copy the vectors back and forth. Also, this trick won't work with non-
    >> homogeneous records.

    >
    > Agreed. I can confirm that C++ is much better for my kind of number
    > chrunching tasks. I have to solve big nonlinear optimization problems
    > and switched from Java to C++ two years ago. I'm not looking back. The
    > ability to write user-defined types that are handled like builtin
    > types (no indirection, no heap allocations) combined with "true
    > genericity" is key.
    >
    >>> In practice,
    >>> Clojure access to Java arrays, even primitive arrays, seems to
    >>> be slow. This may be addressed in a future version.

    >
    > Are we talking about the language "Clojure" (lisp dialect) or the
    > cloSure proposal for Java 7?


    The former.

    And since you clearly didn't even know what "Clojure" was referring to,
    your claims that C++ is necessarily "much better" ring hollow.

    In fact, Clojure, having macros and access to Java arrays, is capable of
    working with contiguous blocks of doubles or similarly and treating
    them as structured into discrete complex numbers, vectors, or
    what-have-you, and is capable of "true genericity". Lisps in general are
    much more capable of "true genericity" than C++ is.

    Even Java can be made to perform at C-like speeds with suitable
    structuring of your data; it's just that you can't always encapsulate
    that data into discrete Java objects and keep that performance.
    Although, objects allocated sequentially tend to be allocated at
    close-together memory locations in Java, and the new G-1 garbage
    collector should help further with keeping objects that are used
    together close together in memory, improving locality of memory access
    patterns.

    Regardless, actual benchmark numbers show all three languages achieving
    comparable speeds at comparable numerical tasks, IF the code in each
    language is performance-tuned by someone reasonably expert in the use of
    that language. Of course, when an ignoramus such as either of the
    preceding posters, who clearly know only the bare bones about Java and
    nothing at all about Clojure, attempt to write performant code in those
    languages, they can expect to do poorly.

    And of course, the savings from using a smart algorithm beat a
    few-percent or even a few-tens-of-percent difference in raw execution
    speed anyday.

    (defn fib[n]
    (nth (map second (iterate (fn [[a b]] [b (+ a b)]) [0 1])) n))

    in clojure will be hugely faster than

    int fib (int n) {
    if (n == 0 || n == 1) return 1;
    return fib(n - 1) + fib(n - 2);
    }

    anyday. (And won't wrap after 1836311903, or, worse, after 28657, either.)
    Oxide Scrubber, Jul 29, 2009
    #4
  5. fft1976

    fft1976 Guest

    Re: Clojure vs Java speed

    On Jul 29, 1:18 am, Oxide Scrubber <> wrote:
    > fft1976 failed for the second time to respect the Followup-To header:
    >


    Everyone who decides to reply to this joker, watch out: he's silently
    adding "Followup-To: alt.olympics" to his messages, trying to trick
    you into not posting here, so he would have the last word.

    Is this what Clojure fanboys must resort to when they lose an
    argument? I thought Haskell and Common Lisp had the worst fanboys till
    today.
    fft1976, Jul 29, 2009
    #5
  6. Re: Clojure vs Java speed

    fft1976 wrote:
    > On Jul 29, 1:18 am, Oxide Scrubber <> wrote:
    >> fft1976 failed for the second time to respect the Followup-To header:

    >
    > Everyone who decides to reply to this joker, watch out: he's silently
    > adding "Followup-To: alt.olympics" to his messages


    No, I am not. I am adding a followup-to for atl.olympics. (Note spelling.)

    It's currently an empty newsgroup, so it seemed appropriate as a place
    to redirect your useless and illogical flamage.

    > Is this what Clojure fanboys must resort to when they lose an
    > argument?


    I wouldn't know, since that's never happened to me.
    Oxide Scrubber, Jul 29, 2009
    #6
  7. fft1976

    Lew Guest

    Re: Clojure vs Java speed

    fft1976 wrote:
    > On Jul 29, 1:18 am, Oxide Scrubber <> wrote:
    >> fft1976 failed for the second time to respect the Followup-To header:
    >>

    >
    > Everyone who decides to reply to this joker, watch out: he's silently
    > adding "Followup-To: alt.olympics" to his messages, trying to trick
    > you into not posting here, so he would have the last word.
    >
    > Is this what Clojure fanboys must resort to when they lose an
    > argument? I thought Haskell and Common Lisp had the worst fanboys till
    > today.


    fft1976 is the one who "silently" decided to drag this flamewar into
    clj.programmer. We were doing just fine without it.

    f/u set to comp.programming and please keep your flamewar out of clj groups.

    --
    Lew
    Lew, Jul 29, 2009
    #7
  8. fft1976

    Arne Vajhøj Guest

    Re: Clojure vs Java speed

    Oxide Scrubber wrote:
    > fft1976 wrote:
    >> Is this what Clojure fanboys must resort to when they lose an
    >> argument?

    >
    > I wouldn't know, since that's never happened to me.


    Thanks for that very informative comment !

    :)

    Arne
    Arne Vajhøj, Jul 30, 2009
    #8
  9. fft1976

    fft1976 Guest

    On Jul 29, 12:24 pm, Jon Harrop <> wrote:

    > > This is fanboy fantasy, not reality.

    >
    > Yes. Clojure has some nice features but its most serious deficiencies are
    > inherited from the JVM and there is nothing Clojure can do about it, e.g.
    > value types and TCO.


    Not as far as speed is concerned, in practice. If you give up 1.5x
    speed by going from C++ to Java, and 5-10 by going from Java to
    Clojure [1], than the latter is much more relevant.

    I actually think 1.5x is a good trade for memory safety, as I stated.
    It's beyond me why this "" fella decided to argue
    about it, when he obviously knows nothing about number crunching. What
    a nut case.

    [1] http://groups.google.com/group/clojure/msg/92b33476c0507478
    fft1976, Jul 30, 2009
    #9
  10. fft1976

    Lew Guest

    Re: Clojure vs Java speed

    fft1976 wrote:
    > I actually think 1.5x is a good trade for memory safety, as I stated.
    > It's beyond me why this "" fella decided to argue
    > about it, when he obviously knows nothing about number crunching. What
    > a nut case.


    Flame war, flame war, flame war. Go on to comp.programming and have a great time.

    --
    Lew
    Lew, Jul 30, 2009
    #10
  11. On Jul 29, 2:54 am, SG <> wrote:
    > On 29 Jul., 07:55, fft1976 <> wrote:
    >
    > > On Jul 28, 9:46 pm, Oxide Scrubber <> wrote:

    >
    > > > The JIT can't, but the coder can. If you want a vector of N
    > > > double-precision complex numbers in Java that is contiguous in memory,
    > > > for example, you could use a Java array of 2xN doubles and index into it
    > > > appropriately.

    >
    > > This is fanboy fantasy, not reality. If I have a library for dealing
    > > with 3D vectors, I'm not going to lay out my data in flat arrays and
    > > copy the vectors back and forth. Also, this trick won't work with non-
    > > homogeneous records.

    >
    > Agreed. I can confirm that C++ is much better for my kind of number
    > chrunching tasks. I have to solve big nonlinear optimization problems
    > and switched from Java to C++ two years ago. I'm not looking back. The
    > ability to write user-defined types that are handled like builtin
    > types (no indirection, no heap allocations) combined with "true
    > genericity" is key.


    I second this opinion. Statically typed UDT + templates and also
    operator and function overloading are big wins for C++ numerical
    work. Despite its faults, C++ provides an interesting and useful
    mix of capabilities in my opinion and C++0x makes it even better.

    KHD
    Keith H Duggar, Jul 30, 2009
    #11
  12. Re: Clojure vs Java speed

    Jon Harrop wrote:
    > fft1976 wrote:
    >> On Jul 29, 12:24 pm, Jon Harrop <> wrote:
    >>>> This is fanboy fantasy, not reality.
    >>> Yes. Clojure has some nice features but its most serious deficiencies are
    >>> inherited from the JVM and there is nothing Clojure can do about it, e.g.
    >>> value types and TCO.

    >> Not as far as speed is concerned, in practice. If you give up 1.5x
    >> speed by going from C++ to Java, and 5-10 by going from Java to
    >> Clojure [1], than the latter is much more relevant.

    >
    > Lack of value types can cost you a lot more than 1.5x though. Try writing an
    > FFT over boxed complexes and Java and compare with unboxed in C99, for
    > example.


    Clojure has TCO; you just have to make your use of it explicit (and then
    the compiler alerts you if it's not really in tail position).

    I'm not sure what you mean by "value types". If you mean immutable types
    with value-equality semantics remaining consistent over time, then
    Clojure is chock full of them, even its collection types can be used as
    value types, so as keys in maps for instance.

    If you mean non-pointer types, Clojure has access to the full range of
    Java non-pointer types: boolean, byte, short, int, long, float, double,
    and char.

    It can't currently pass them across function call boundaries without
    boxing and unboxing, but you can work around that using definline or a
    macro.

    > This goes way beyond number crunching though. Lots of applications benefit
    > enormously from value types. They are used extensively in the .NET
    > framework.


    The JVM has several non-pointer types too, and does not have the
    Microsoft taint.
    Oxide Scrubber, Jul 31, 2009
    #12
  13. Arne Vajhøj, Jul 31, 2009
    #13
  14. Re: Clojure vs Java speed

    Jon Harrop wrote:
    > Oxide Scrubber wrote:
    >> Jon Harrop wrote:
    >>> You cannot write code that is both that short and that efficient in
    >>> Clojure.

    >> You can write code that is that efficient in Clojure...
    >> Your "value types" are overrated anyway.

    >
    > Look at vertices in XNA for a simple example where value types on .NET
    > facilitate efficient direct interop with the graphics hardware.


    If you want to do direct interop with the graphics hardware on the JVM,
    you use Java2D/Java3D.

    >>>>>> This is fanboy fantasy, not reality.
    >>>>> Yes.
    >>>> Stop attacking me.
    >>> I am not attacking you.

    >> Sure you are. I wrote truth, and in response to that I got dumped on
    >> with a steaming load of ad hominems.

    >
    > Ad hominem means personal attack.


    Actually, "argumentum ad hominem" means "argument against the man",
    which means instead of arguing against a point someone made you argued
    that the identity or nature of the person making it somehow invalidates
    it. The identity or nature of the person is, however, irrelevant, so
    such arguments are fallacies.

    Besides, calling me a "fanboy" whilst implying I'm delusional IS a
    personal attack.

    >>> Clojure offers trampolines to cover more general cases of indirect tail
    >>> calls between different functions but it is much slower than real tail
    >>> call elimination.

    >> Balderdash.

    >
    > [argues some more]


    Listen up, fuckface. I have personally written number-crunching Clojure
    code and measured its performance. You are asking me to disbelieve the
    evidence of my own eyes, just because your faith asserts that I can't
    possibly have seen what I've seen.

    I think we're done here. Not only are you clearly irrational, but you've
    managed to frustrate me enough for me to use a cuss word. :p

    >>>> I'm not sure what you mean by "value types".
    >>> http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx

    >> I'm sorry, but I am asking you, not some web site (and especially not
    >> some Microsoft web site), what you mean. If you don't want to actually
    >> have a constructive dialog, feel free to STFU. Otherwise, actually say
    >> something.

    >
    > Please familiarize yourself with the basic terminology


    Please do not condescend to me. I've been working with, and programming,
    computers for a quarter-century, and I've been doing number crunching
    for almost as long. And I, unlike you, base my beliefs upon evidence
    instead of faith.

    >>>> If you mean non-pointer types, Clojure has access to the full range of
    >>>> Java non-pointer types: boolean, byte, short, int, long, float, double,
    >>>> and char.
    >>> The ability to define custom value types is extremely valuable, most
    >>> notably in the context of technical computing where you want 32- and
    >>> 64-bit complex numbers, 2d vectors, 3d vectors in homogeneous
    >>> coordinates, quaternions and dozens of other types to be representable
    >>> without the overhead of boxing, heap allocating, stressing the garbage
    >>> collector and so on.

    >> First of all, I explained in previous posts that you can do that in
    >> Java, and with full data abstraction in Clojure.

    >
    > No, this is impossible to do


    But I've done it.

    This is it. You basically just called me a liar there. I think I'm done
    trying to reason with you. I judge that your reputation as a troll is
    well-deserved. (Note that I had ignored that until now, choosing to base
    my opinion upon evidence rather than hearsay. That is the difference
    between us. But now that enough evidence is in, I find myself agreeing
    with the hearsay. Funny, that.)

    > array of structs that contain both ints and floats, for example. There is
    > no way to represent that on the JVM because you only have an array of ints
    > or an array of floats but not an array of structs composed of both ints and
    > floats.


    I don't suppose the concept of keeping separate-but-parallel arrays of
    ints and floats (and wrapping this structure in a data abstraction
    layer) occurred to you?

    >> Second, if you define classes like Complex and Vect in Java with fields
    >> of type double, the doubles don't get individually boxed.

    >
    > But the complex numbers and vectors do


    So?

    > which incurs massive performance degradation.


    Codswallop.

    I've debunked that argument enough times already; I won't bother to
    repeat myself again here.

    >> Third, the overhead of "heap allocating, stressing the garbage collector
    >> and so on" in a modern JVM is about the same as the overhead of stack
    >> allocating, on an amortized per-object basis: a pointer bump and
    >> whatever construction is done to write values to memory.

    >
    > No


    Yes.

    Until you have learned something about the performance characteristics
    of *modern* garbage collectors, you are not qualified to continue this
    argument.

    >>>> It can't currently pass them across function call boundaries without
    >>>> boxing and unboxing, but a) if the function call is consistent, the JIT
    >>>> can inline it and optimize away the boxing and unboxing, and b) Clojure
    >>>> has macros, so it's possible to inline a function not being itself
    >>>> passed across function calls without losing the function-call syntax.
    >>> Only if your code is written entirely in Clojure which will not be the
    >>> case

    >> Why won't it?

    >
    > Because you will be calling library functions.


    To do the numerics? Perhaps not. And if so, they shall be functions in a
    high-performance numerics library. Either way, you lose.

    >>> you are on the JVM to reuse existing Java libraries

    >> Laughable. You may be on the JVM to get portability, or a top-notch GC,
    >> or any combination of things. And if you are on the JVM to use existing
    >> Java libraries, that usage might not be in the numeric parts of the
    >> code...

    >
    > Or it might be JLAPACK


    Or it might be Santa Claus. You can throw all kinds of "might be"s out
    there, and as long as it also "might not be", you still lose.

    > or it might be OpenGL which has had its performance degraded


    That's news to me. I'm sure it'll be news to id Software too when they
    hear it.

    >> Last, but certainly not least, the Java libraries you're using might be
    >> existing high-performance numerics libraries for Java! Or Java wrappers
    >> around GMP or a similar native-code library.

    >
    > The JVM is also extremely slow to invoke external code (an order of
    > magnitude slower than the CLR, for example) so those libraries also suffer
    > from limitations of the JVM.


    That would be a problem if you were stupid enough to call into JNI for
    every single add, subtract, or multiply. Normally, you'd have larger,
    longer-running tasks (perhaps entire number-crunching loops) called via
    JNI, if you were using JNI. Not that you have to to get performance on a
    *modern* JVM.

    >>> but those libraries expose these deficiencies of the VM by providing
    >>> non-generic interfaces.

    >> A bit of Clojure magic could wrap these in much nicer interfaces even so
    >> -- and, using macros or definline judiciously, without any run-time
    >> overhead.

    >
    > Absolutely.


    Ah, you're finally starting to see reason.

    > Clojure code is either short and slow or long and fast


    You have just capitulated by admitting that Clojure code can be fast.

    > but not short and fast like the F# example I already posted.


    Well, actually, if you tuck those support macros and functions away, the
    same algorithm can be expressed just as concisely and run just as fast;
    though it will call those macros and functions. Macros and functions
    that can be reused in many such algorithms, or even made available as a
    library. Using them is no more "cheating" or "bloating" than using GMP
    from your C code would be.

    >>> As an aside, the JVM even screwed up generics by using type erasure
    >>> instead of monomorphization and per-type instantiation at JIT => when the
    >>> JVM fails to optimize, generics are extremely slow.

    >> That's why if you need performance you use -server. Besides, Clojure
    >> doesn't care about Java's generics making them irrelevant.

    >
    > Not if you want to compare with languages like F# that inherit
    > well-implemented generics from their VM.


    Compare them regarding what? Not speed. It looks like you're on about
    static typing now, which is a completely different flamewar. And one
    this newsgroup has already had recently, if I'm not mistaken.

    >>>> Just make a macro version of the function, or even a macro that can take
    >>>> a function's source code and spit out a macro version of that function.
    >>> That only works if the entire source is written in Clojure.

    >> It works if that particular function's source is.

    >
    > You cannot write "a macro that can take a function's source code and spit
    > out a macro version of that function" unless all of those functions are in
    > Clojure.


    Only the function to be macro-ized and the functions calling it have to
    be written in Clojure. Furthermore, your objection is begging the
    question. It assumes what you'd set out to prove, namely that "written
    in Clojure = bad".

    >>> I am the author of the world's most profitable book on functional
    >>> programming.

    >> Let me guess: "Functional Programming for Dummies" or something on that
    >> level?

    >
    > OCaml


    Irrelevant. We are discussing Clojure and other JVM languages.

    > and F#


    Microsoft associated and therefore evil.

    >> Many of the "problems" you cite go away with aggressive JIT
    >> optimization, which you get if you use the -server flag when you launch
    >> the JVM.

    >
    > No


    Yes.

    You have lost.

    Have a nice day.
    Oxide Scrubber, Jul 31, 2009
    #14
  15. Re: Clojure vs Java speed

    Jon Harrop wrote:
    > Oxide Scrubber wrote:
    >> Jon Harrop wrote:
    >>> fft1976 wrote:
    >>>> On Jul 29, 12:24 pm, Jon Harrop <> wrote:
    >>>>>> This is fanboy fantasy, not reality.
    >>>>> Yes. Clojure has some nice features but its most serious deficiencies
    >>>>> are inherited from the JVM and there is nothing Clojure can do about
    >>>>> it, e.g. value types and TCO.
    >>>> Not as far as speed is concerned, in practice. If you give up 1.5x
    >>>> speed by going from C++ to Java, and 5-10 by going from Java to
    >>>> Clojure [1], than the latter is much more relevant.
    >>> Lack of value types can cost you a lot more than 1.5x though. Try writing
    >>> an FFT over boxed complexes and Java and compare with unboxed in C99, for
    >>> example.

    >> Clojure has TCO; you just have to make your use of it explicit (and then
    >> the compiler alerts you if it's not really in tail position).

    >
    > Clojure has recur and trampolines, both of which are workarounds for the
    > lack of TCO.


    They are means of implementing TCO.

    >> I'm not sure what you mean by "value types".

    >
    > http://msdn.microsoft.com/en-us/library/s1ax56ch(VS.80).aspx


    I'm sorry, but I prefer people to actually discuss something rather than
    try to send me off to some web site. Especially some Microsoft web site.

    >>> This goes way beyond number crunching though. Lots of applications
    >>> benefit enormously from value types. They are used extensively in the
    >>> .NET framework.

    >> The JVM has several non-pointer types too...

    >
    > Value types are user-defined non-pointer types, i.e. structs.


    There are several different uses of the phrase "value types". Why did it
    take you this long to disambiguate?

    > For example, you can define a complex type as a struct of two doubles
    > or a Vertex type as a struct of three floats and three int16s.


    Fascinating.

    > In Clojure, you can workaround the lack of arrays of complex numbers using
    > arrays of floats and syntactic abstraction to fudge the difference
    > (Greenspunning instantiation-per-type generics which the JVM also lacks)
    > but you cannot work around the general case.


    Sure you can. For instance, for an array of your oddball Vertex type
    above, use an array of 3N floats and a separate array of 3N int16s.
    Allocate them one right after the other and you'll still have good
    memory access locality, and you won't have much unboxing overhead (two
    "boxes" means not much more unboxing than one and far less than N).

    > This incurs huge performance degradation for programs on the JVM


    Hogwash.

    > and can make direct interop impossible (e.g. the JVM cannot express
    > XNA).


    Why do you think the JVM should have to "express XNA", whatever that
    means? It can probably either use something else at least as good, or
    else do it with one extra layer of indirection, a layer that becomes
    very cheap after JIT optimization and hardware branch prediction and
    caching.

    Regardless, it becomes apparent (from all your mentions of F# and
    microsoft.com URLs) that you are a Microsoft fanboi and therefore
    religiously opposed to the JVM because, like Linux, it's one of the
    things that Microsoft hates most: a competitor that just won't roll over
    and die (DR-DOS), or be bought out (Yahoo), or be sued into submission
    (TomTom); indeed, Sun had the gall to actually sue Microsoft and win once!

    Well, either that or you're just a hypocrite and perhaps even a liar.
    How else to explain your posts to the Clojure mailing list, some of them
    directly contradicting things you've said here (including asserting, at
    least twice, that Clojure numeric code can run at native-code speeds).
    Oxide Scrubber, Jul 31, 2009
    #15
  16. fft1976

    Lew Guest

    Re: Clojure vs Java speed

    Oxide Scrubber wrote:
    >>> I'm not sure what you mean by "value types".

    >


    Jon Harrop wrote:
    >> http://msdn.microsoft.com/en-us/library/s1ax56ch(VS.80).aspx

    >


    Oxide Scrubber wrote:
    > I'm sorry,


    Are you? Are you really?

    > but I prefer people to actually discuss something rather than
    > try to send me off to some web site. Especially some Microsoft web site.
    >


    Get off your high horse. Referencing a link is a perfectly legitimate
    way to provide basic information such as that for which you ask. You
    asked a question, he provided the information. That you for some
    inexplicable reason want him to paraphrase a link that clearly and
    succinctly answers your question is not his problem. How about you
    accept his perfectly valid and comprehensive answer?

    > There are several different uses of the phrase "value types". Why did it
    > take you this long to disambiguate?
    >


    Others had no trouble whatsoever with the term. The moment you asked,
    a couple of people responded with answers. Any faster and they'd've
    answered before you asked.

    > Regardless, it becomes apparent (from all your mentions of F# and
    > microsoft.com URLs) that you are a Microsoft fanboi [sic] and therefore
    > religiously opposed to the JVM because, like Linux, it's one of the


    Straw-man and ad hominem arguments.

    > things that Microsoft hates most: a competitor that just won't roll over
    > and die (DR-DOS), or be bought out (Yahoo), or be sued into submission
    > (TomTom); indeed, Sun had the gall to actually sue Microsoft and win once!
    >


    Your answer is somewhat off from the discussion, but taking point by
    point:

    Microsoft doesn't seem to show any emotion whatsoever, let alone hate,
    with respect to the incidents you cited. DR-DOS killed itself; it
    wasn't good enough to sustain itself in the market. Microsoft didn't
    show any problem when Yahoo resisted the buyout; it simply started
    another search-engine effort. Sun got very palsy-walsy with Microsoft
    a couple of years ago, dropped the suit, and offered a joint
    announcement with Microsoft that they were happy with each other.
    Hardly evidence of hate.

    Businesses compete. That's inherent to the capitalist system.
    Businesses that compete effectively get to stay in business. That's
    nothing for which to be angry with Microsoft. Indeed, you seem to be
    showing a stronger interest in bashing Microsoft than addressing the
    logic of Dr. Jon's posts.

    I realize that it's fashionable to bash Microsoft, but it doesn't
    prove anything.

    > Well, either that or you're just a hypocrite and perhaps even a liar.


    Ad hominem name-calling and completely inappropriate. Also, you
    provide no evidence of hypocrisy or lies; such accusations put the
    burden of proof on you, otherwise they're just pointless flaming.

    > How else to explain your posts to the Clojure mailing list, some of them
    > directly contradicting things you've said here (including asserting, at
    > least twice, that Clojure numeric code can run at native-code speeds).


    Perhaps he was discussing primitive numerics, for which the discussion
    of value types would not apply. Such points would not apply to matrix
    math, of course, and thus there would be no contradiction. Not being
    a subscriber to those lists, I don't know. Perhaps you could quote
    some of the allegedly contradictory posts verbatim for those of us who
    follow in a different newsgroup?

    Try to avoid flaming, and focus on presentation of evidence and logic.

    --
    Lew
    Lew, Jul 31, 2009
    #16
  17. On Jul 30, 12:12 pm, Jon Harrop <> wrote:
    > Keith H Duggar wrote:
    > > On Jul 29, 2:54 am, SG <> wrote:
    > >> On 29 Jul., 07:55, fft1976 <> wrote:
    > >> Agreed. I can confirm that C++ is much better for my kind of number
    > >> chrunching tasks. I have to solve big nonlinear optimization problems
    > >> and switched from Java to C++ two years ago. I'm not looking back. The
    > >> ability to write user-defined types that are handled like builtin
    > >> types (no indirection, no heap allocations) combined with "true
    > >> genericity" is key.

    >
    > > I second this opinion. Statically typed UDT + templates and also
    > > operator and function overloading are big wins for C++ numerical
    > > work. Despite its faults, C++ provides an interesting and useful
    > > mix of capabilities in my opinion and C++0x makes it even better.

    >
    > FWIW, "inline" in F# provides the same benefits in an easier to use form. It
    > really rocks. :)


    Here is a toy C++ numerical example that uses templates, function
    overloading, and operator overloading to provide a generic golden
    section algorithm that will work for any UDT (and built-in types)
    for which one provides the needed overloads and specializations.

    template < class Vector >
    Vector
    golden_section (
    Vector const & xa
    , Vector const & xm
    , Vector const & xb
    ) {
    Vector const ma ( xa - xm ) ;
    Vector const mb ( xb - xm ) ;

    return mag(ma) > mag(mb) ?
    xm + (ma * Constants< Scalar<Vector> >::goldenRatio()) :
    xm + (mb * Constants< Scalar<Vector> >::goldenRatio()) ;
    }

    Can you please show how F#'s 'inline' provides the same benefits?
    Ie how does F# with 'inline' support the above generic algorithm?

    KHD
    Keith H Duggar, Jul 31, 2009
    #17
  18. fft1976

    Arne Vajhøj Guest

    Re: Clojure vs Java speed

    Keith H Duggar wrote:
    > On Jul 30, 12:12 pm, Jon Harrop <> wrote:
    >> Keith H Duggar wrote:
    >>> On Jul 29, 2:54 am, SG <> wrote:
    >>>> On 29 Jul., 07:55, fft1976 <> wrote:
    >>>> Agreed. I can confirm that C++ is much better for my kind of number
    >>>> chrunching tasks. I have to solve big nonlinear optimization problems
    >>>> and switched from Java to C++ two years ago. I'm not looking back. The
    >>>> ability to write user-defined types that are handled like builtin
    >>>> types (no indirection, no heap allocations) combined with "true
    >>>> genericity" is key.
    >>> I second this opinion. Statically typed UDT + templates and also
    >>> operator and function overloading are big wins for C++ numerical
    >>> work. Despite its faults, C++ provides an interesting and useful
    >>> mix of capabilities in my opinion and C++0x makes it even better.

    >> FWIW, "inline" in F# provides the same benefits in an easier to use form. It
    >> really rocks. :)

    >
    > Here is a toy C++ numerical example that uses templates, function
    > overloading, and operator overloading to provide a generic golden
    > section algorithm that will work for any UDT (and built-in types)
    > for which one provides the needed overloads and specializations.
    >
    > template < class Vector >
    > Vector
    > golden_section (
    > Vector const & xa
    > , Vector const & xm
    > , Vector const & xb
    > ) {
    > Vector const ma ( xa - xm ) ;
    > Vector const mb ( xb - xm ) ;
    >
    > return mag(ma) > mag(mb) ?
    > xm + (ma * Constants< Scalar<Vector> >::goldenRatio()) :
    > xm + (mb * Constants< Scalar<Vector> >::goldenRatio()) ;
    > }
    >
    > Can you please show how F#'s 'inline' provides the same benefits?
    > Ie how does F# with 'inline' support the above generic algorithm?


    Can you explain why you posted to comp.lang.java.programmer ?

    Arne
    Arne Vajhøj, Jul 31, 2009
    #18
  19. Re: Clojure vs Java speed

    On Jul 31, 3:46 pm, Arne Vajh√âˆj <> wrote:
    > Keith H Duggar wrote:
    > > On Jul 30, 12:12 pm, Jon Harrop <> wrote:
    > >> Keith H Duggar wrote:
    > >>> On Jul 29, 2:54 am, SG <> wrote:
    > >>>> On 29 Jul., 07:55, fft1976 <> wrote:
    > >>>> Agreed. I can confirm that C++ is much better for my kind of number
    > >>>> chrunching tasks. I have to solve big nonlinear optimization problems
    > >>>> and switched from Java to C++ two years ago. I'm not looking back. The
    > >>>> ability to write user-defined types that are handled like builtin
    > >>>> types (no indirection, no heap allocations) combined with "true
    > >>>> genericity" is key.
    > >>> I second this opinion. Statically typed UDT + templates and also
    > >>> operator and function overloading are big wins for C++ numerical
    > >>> work. Despite its faults, C++ provides an interesting and useful
    > >>> mix of capabilities in my opinion and C++0x makes it even better.
    > >> FWIW, "inline" in F# provides the same benefits in an easier to use form. It
    > >> really rocks. :)

    >
    > > Here is a toy C++ numerical example that uses templates, function
    > > overloading, and operator overloading to provide a generic golden
    > > section algorithm that will work for any UDT (and built-in types)
    > > for which one provides the needed overloads and specializations.

    >
    > > template < class Vector >
    > > Vector
    > > golden_section (
    > > Vector const & xa
    > > , Vector const & xm
    > > , Vector const & xb
    > > ) {
    > > Vector const ma ( xa - xm ) ;
    > > Vector const mb ( xb - xm ) ;

    >
    > > return mag(ma) > mag(mb) ?
    > > xm + (ma * Constants< Scalar<Vector> >::goldenRatio()) :
    > > xm + (mb * Constants< Scalar<Vector> >::goldenRatio()) ;
    > > }

    >
    > > Can you please show how F#'s 'inline' provides the same benefits?
    > > Ie how does F# with 'inline' support the above generic algorithm?

    >
    > Can you explain why you posted to comp.lang.java.programmer ?


    The thread has been cross-posted from the beginning. You will
    need to ask either fft1976 or SG why it is so.

    KHD
    Keith H Duggar, Jul 31, 2009
    #19
  20. Re: Clojure vs Java speed

    Keith H Duggar wrote:
    > On Jul 31, 3:46 pm, Arne Vajh√âˆj <> wrote:
    >> Keith H Duggar wrote:
    >>> On Jul 30, 12:12 pm, Jon Harrop <> wrote:
    >>>> Keith H Duggar wrote:
    >>>>> On Jul 29, 2:54 am, SG <> wrote:
    >>>>>> On 29 Jul., 07:55, fft1976 <> wrote:
    >>>>>> Agreed. I can confirm that C++ is much better for my kind of number
    >>>>>> chrunching tasks. I have to solve big nonlinear optimization problems
    >>>>>> and switched from Java to C++ two years ago. I'm not looking back. The
    >>>>>> ability to write user-defined types that are handled like builtin
    >>>>>> types (no indirection, no heap allocations) combined with "true
    >>>>>> genericity" is key.
    >>>>> I second this opinion. Statically typed UDT + templates and also
    >>>>> operator and function overloading are big wins for C++ numerical
    >>>>> work. Despite its faults, C++ provides an interesting and useful
    >>>>> mix of capabilities in my opinion and C++0x makes it even better.
    >>>> FWIW, "inline" in F# provides the same benefits in an easier to use form. It
    >>>> really rocks. :)
    >>> Here is a toy C++ numerical example that uses templates, function
    >>> overloading, and operator overloading to provide a generic golden
    >>> section algorithm that will work for any UDT (and built-in types)
    >>> for which one provides the needed overloads and specializations.
    >>> template < class Vector >
    >>> Vector
    >>> golden_section (
    >>> Vector const & xa
    >>> , Vector const & xm
    >>> , Vector const & xb
    >>> ) {
    >>> Vector const ma ( xa - xm ) ;
    >>> Vector const mb ( xb - xm ) ;
    >>> return mag(ma) > mag(mb) ?
    >>> xm + (ma * Constants< Scalar<Vector> >::goldenRatio()) :
    >>> xm + (mb * Constants< Scalar<Vector> >::goldenRatio()) ;
    >>> }
    >>> Can you please show how F#'s 'inline' provides the same benefits?
    >>> Ie how does F# with 'inline' support the above generic algorithm?

    >> Can you explain why you posted to comp.lang.java.programmer ?

    >
    > The thread has been cross-posted from the beginning. You will
    > need to ask either fft1976 or SG why it is so.


    I assume that your newsreader have a little feature where you can
    trim the groups being posted to.

    A comparison between C++ and F# *may* be on topic in
    comp.lang.functional, but it is utterly irrelevant in
    comp.lang.java.programmer !

    Arne
    Arne Vajhøj, Jul 31, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Xah Lee
    Replies:
    18
    Views:
    2,263
    Arne Vajhøj
    Nov 28, 2008
  2. fft1976
    Replies:
    7
    Views:
    770
    jgrant27
    Jun 19, 2009
  3. Shaguf
    Replies:
    0
    Views:
    145
    Shaguf
    Dec 11, 2008
  4. rahul

    Clojure based objects

    rahul, Dec 8, 2009, in forum: Perl Misc
    Replies:
    4
    Views:
    124
    rahul
    Dec 8, 2009
  5. Eric Normand

    Introduction to Clojure Videos

    Eric Normand, Feb 19, 2013, in forum: Java
    Replies:
    0
    Views:
    242
    Eric Normand
    Feb 19, 2013
Loading...

Share This Page