September 19, 2013
On 19/09/2013 11:06, deadalnix wrote:
>
>>> *Java's sluggish performance was what made me look for alternatives
>>> in the first place, and I found D.
>>
>> I accept this as true as it is a statement by you about your decision
>> making, but Java 8 is not Java 1. Early desktop Java was pure
>> interpretation, and hence slow. Modern Java, via the JIT, generally
>> executes native code. With Java 7 and method handles and invokedynamic,
>> the world changed even more and now computationally intensive codes can
>> run basically as fast using Java as using C, C++, Fortran, D, Rust, Go.
>> (After initial "warm up" of the JIT.)
>>
>
> Yes, the warm up is usually a severe drawback for user applications.
> Server app do not suffer from it that much. I guess that is why java is
> so much used server side, but not that much to create GUI apps.

Yeah, tell me about it. :/
When I was writing the new parser for DDT I explored and tested a few optimizations that the JVM does to ellide object allocations (essentially escape analysis to see when an object can be treated as value object, and deallocated automatically at the end of some scope).
I wanted to use a certain pervasive code idiom in the parser that would make the code more elegant, but less performant if this optimization was not made.
( http://www.meetup.com/Londonjavacommunity/messages/52187462/ )
Fortunately the JVM is its later incarnations is quite smart in its escape analysis, but unfortunately this is all done at runtime, whereas a lot of it could be performed compile-time. :( But it seems the Java folks (at least for OpenJDK) have a big aversion to performing any kind of compile-time optimizations, even though a lot could be done here.


-- 
Bruno Medeiros - Software Engineer
September 19, 2013
On 19 September 2013 09:31, Russel Winder <russel@winder.org.uk> wrote:
> On Thu, 2013-09-19 at 00:53 +0100, Iain Buclaw wrote:
> […]
>> Java itelf is a very basic language to allow this to be possible.  But the library implementation denies this, and I don't see native support beyond JNI.
>
> JNA
>
> But your core point as I infer it is valid. Running on the JVM it is best not to have to use native code libraries. I think the NAG Java adaptor to it's Fortran and C++ libraries will not gain any traction.
>
> The new interest is getting support for the heterogeneous processors on the horizon. In threads elsewhere we started debating GPGPU support in D exactly because it will be a necessity in future processors. Java has two plays in this game already.
>

I think I had a bit too much to drink (see cocktail thread).

But yes, that is the general essence, though I was more leaning on Java's class hierarchy and being virtual by default. This is something that you can't get away from in native code, where as in most Java JIT implementations, they are designed explicitly for lots of virtual calls, such as the ability to inline virtual functions at runtime which makes virtual calls as cheap as non-virtual.

In native code however, there is no way for the compiler to optimise this at compile-time, and the slowdown grinds as the code base grows (gcc's libjava is 230K LOC for example), and the result is that you end up paying through the nose without asking - we've already discussed this plentiful in D's design choice to go virtual by default.

-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
September 19, 2013
Am 19.09.2013 19:44, schrieb Bruno Medeiros:
> On 19/09/2013 11:06, deadalnix wrote:
>>
>>>> *Java's sluggish performance was what made me look for alternatives
>>>> in the first place, and I found D.
>>>
>>> I accept this as true as it is a statement by you about your decision
>>> making, but Java 8 is not Java 1. Early desktop Java was pure
>>> interpretation, and hence slow. Modern Java, via the JIT, generally
>>> executes native code. With Java 7 and method handles and invokedynamic,
>>> the world changed even more and now computationally intensive codes can
>>> run basically as fast using Java as using C, C++, Fortran, D, Rust, Go.
>>> (After initial "warm up" of the JIT.)
>>>
>>
>> Yes, the warm up is usually a severe drawback for user applications.
>> Server app do not suffer from it that much. I guess that is why java is
>> so much used server side, but not that much to create GUI apps.
>
> Yeah, tell me about it. :/
> When I was writing the new parser for DDT I explored and tested a few
> optimizations that the JVM does to ellide object allocations
> (essentially escape analysis to see when an object can be treated as
> value object, and deallocated automatically at the end of some scope).
> I wanted to use a certain pervasive code idiom in the parser that would
> make the code more elegant, but less performant if this optimization was
> not made.
> ( http://www.meetup.com/Londonjavacommunity/messages/52187462/ )
> Fortunately the JVM is its later incarnations is quite smart in its
> escape analysis, but unfortunately this is all done at runtime, whereas
> a lot of it could be performed compile-time. :( But it seems the Java
> folks (at least for OpenJDK) have a big aversion to performing any kind
> of compile-time optimizations, even though a lot could be done here.
>
>


I once read in a blog, an entry from an ex-JVM engineer from Sun, describing that anything that disputed Hotspot JIT capabilities was tabu and ideas about native compilation were frowned upon.

Sadly I don't remember any longer where I read it.

--
Paulo
September 19, 2013
Am 19.09.2013 19:21, schrieb Andrei Alexandrescu:
> On 9/19/13 6:05 AM, PauloPinto wrote:
>>> In java, all classes are dynamically loadable, and most functions are
>>> virtual. This is a deal breaker for the AOT.
>>
>> Wrong. The Java AOT compilers that target embedded systems produce
>> static binaries.
>
> That's not wrong. Java AOT compilers usually (or at least last time I
> looked) make it clear they support no dynamic loading/invocation etc. so
> in a sense they don't support 100% of Java.
>
> Andrei
>

In Websphere Real Time VM you can have a mixed deployment mode.

Not sure about other AOT compilers.

I was stating the specific case of targeting embedded processors, where I think dynamic loading and reflection are anyway not that relevant.

Even C and C++ are not fully supported in all types of embedded scenarios.


--
Paulo
September 19, 2013
On Thursday, 19 September 2013 at 17:34:21 UTC, Bruno Medeiros wrote:
> I didn't think layout control would be a major issue, except for a very specific type of applications, no? That seems like a very low level optimization.

You can easily get large performance improvements from good memory layout (well over 2x).
September 19, 2013
On Thu, 2013-09-19 at 18:34 +0100, Bruno Medeiros wrote: […]
> I was about to say something similar. Java is no longer under-performant
> to C/C++, etc., for a *certain* class of applications only. Applications
> that mainly do data manipulation, I/O, etc., because the JIT will
> (eventually) compile the Java bytecode to native code.
> So Java really is not behind because of being VM-based instead of fully
> native-based.
> 
> Generally though, I would still say Java is under-performant compared to
> C/C++, etc., although I would say it's mainly due to lack of optional
> manual memory management. Or lack of value-types (which in a way, are a
> form of memory management).
> I didn't think layout control would be a major issue, except for a very
> specific type of applications, no? That seems like a very low level
> optimization.

I am not going to be drawn into a low-level blow-by-blow debate on this, definitely not on this list since it is inherently biased!, but mainly because Andrei will accuse me of being David Bryant again ;-)

There are native code shops and JVM shops (as well as PVM shops, and Ruby shops, etc.) There is a quasi-religious fervour involved in each of these. To be honest I do not care, I am happy working native (D, Go, Rust, C++, but not C) or JVM (Groovy, Scala, Java, Ceylon, Kotlin, Clojure, JRuby, Jython), or PVM (Python), or Ruby. For me there is no absolute best, just a relative best for the client involved. Skills of the team involved at the time, and the overall dependencies of the organizations, matter as much as any absolute notion of best wrt a processor.

I do note though that The Disruptor (by LMAX) is a seriously cool lock free ring buffer based system written entirely in Java.
-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


September 20, 2013
On Thursday, 19 September 2013 at 09:44:30 UTC, Chris wrote:
> Yes, the whole issue of decompilation was also an issue. Funnily enough, a few years ago I wrote an email to Excelsior asking if you guys offer a discount for academia. Our project would have qualified as "non-commercial use". But I never got an answer. So I started looking for alternatives, and here I am now :-)

We respond to all requests that look legit. Sending from a university email address certainly helps, not least because our responses to free email users, especially Gmail, often end up in the Junk Mail folder, probably because they talk about "free", "download", and such...

--
Dmitry
September 20, 2013
On Thursday, 19 September 2013 at 17:55:22 UTC, Iain Buclaw wrote:
> But yes, that is the general essence, though I was more leaning on
> Java's class hierarchy and being virtual by default. This is something
> that you can't get away from in native code, where as in most Java JIT
> implementations, they are designed explicitly for lots of virtual
> calls, such as the ability to inline virtual functions at runtime
> which makes virtual calls as cheap as non-virtual.
>
> In native code however, there is no way for the compiler to optimise
> this at compile-time, and the slowdown grinds as the code base grows
> (gcc's libjava is 230K LOC for example), and the result is that you
> end up paying through the nose without asking - we've already
> discussed this plentiful in D's design choice to go virtual by
> default.

Our AOT compiler does inline virtual calls of non-final methods that are not overloaded in any subclass known at compile time. Of course, there is a runtime check and a backup virtual call, but the check is cheap and code size increase in negligible.

What we don't do (yet) is profile-guided optimizations, but that is on our to-do list.

--
Dmitry
www.ExcelsiorJET.com
September 20, 2013
On Thursday, 19 September 2013 at 17:21:16 UTC, Andrei Alexandrescu wrote:
> On 9/19/13 6:05 AM, PauloPinto wrote:
>>> In java, all classes are dynamically loadable, and most functions are
>>> virtual. This is a deal breaker for the AOT.
>>
>> Wrong. The Java AOT compilers that target embedded systems produce
>> static binaries.
>
> That's not wrong. Java AOT compilers usually (or at least last time I looked) make it clear they support no dynamic loading/invocation etc. so in a sense they don't support 100% of Java.

You have not looked for way too long it seems. Our JVM with AOT compiler passes the official compliance tests (Java Compatibility Kit), which includes reflaction/invocation tests. Of course, if the class being loaded dynamically was known at compile time, it will resolve to the precompiled image, otherwsie, a JIT compiler kicks into action. GCJ has an interpreter serving the same purpose.

We even went a step further and created an interesting technique that enables you to reduce application download size and disk footprint by omitting the unused parts of the Java platform:

http://www.excelsior-usa.com/java-download-size.html

In order to remain spec compliant, the runtime is capable of downloading the omitted on demand. However, for sample apps that you can download from the above URL, there was not a single such download ever.
September 20, 2013
On Thursday, 19 September 2013 at 14:28:04 UTC, deadalnix wrote:
> On Thursday, 19 September 2013 at 13:05:17 UTC, PauloPinto wrote:
>> Wrong. The Java AOT compilers that target embedded systems produce static binaries.
>>
>
> I don't think that address anything. As long as you CAN dynamically load override, then you can't optimize AOT, and if you can't then, it isn't java, but some kind of java like dialect that is amputed of some of its capabilities.
If the most of your classes are known before run and are loaded by known to AOT compiler classloader (99.99% of your classes usually), you can optimize them with AOT. For other classes (that appear at runtime only or loaded by unknown classloader) JVM with AOT may have JIT or interpreter. Excelsior JET runtime has JIT, GCJ has interpreter for this purpose.