Note I am after the FASTEST way to do this in Java (and/or Scala). Is
it better to use the stream based classes, or is it better to do direct
array accesses and do bit shift operations and masks with 0xff etc (to
strip sign extension Java will do otherwise)? I suspect the stream
based approaches would be slower. Sample code that sneaks in:
byte b1 = buf[i++];
byte b2 = buf[i++];
byte b3 = buf[i++];
byte b4 = buf[i++];
int n = (b1 << 24) | ((b2 & 0xff) << 16) | ((b3 & 0xff) << 8) | (b4
& 0xff); // Must mask with 0xff or else sign extension will mess up the
result. Java does not have unsigned bytes or ints!
I was looking into array bounds checks, and what I found via Google
indicated that hotspot leaves in array bounds checks as there was only a
minor performance improvement found in practice. This lead me to wonder
if there is a faster way to do the code since I would be doing lots of
array accesses, each with a bounds check.
Just curious!
Thanks!
Alan
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
>
> Note I am after the FASTEST way to do this in Java (and/or Scala).
> Is it better to use the stream based classes, or is it better to
> do direct array accesses and do bit shift operations and masks
> with 0xff etc (to strip sign extension Java will do otherwise)? I
> suspect the stream based approaches would be slower.
I think you have to try and measure. I've faced the same problem with
image decoding. The ImageI/O API contains an ImageInputStream which is
supposed to have some optimizations - even for bitwise, not only
bytewise operations. When I first worked on it a few years ago, I
found that writing some specific classes for specific cases (e.g.
reading 12 or 16 bits) was faster - in other words, the library didn't
provide the faster code. A few time later, I discovered that some
newer JRE was better and dropped some of my code because it was
useless. So, it's a matter of trying, measuring and re-measuring for
each JRE update.
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
Fabrizio...@tidalwave.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxHTLUACgkQeDweFqgUGxcwxACeLpaYIPiaCCWZe4Q+mSPl4P6x
DMUAn2+o7vmQ32CxIcB+QobTB6Vov4ek
=F5Co
-----END PGP SIGNATURE-----
On 22/07/2010 1:42 AM, Steven Siebert wrote:
> Just ensure you get the correct answer for your situation, when you
> say a lot of access, do you mean read-only or r/w? Concurrency a
> concern? You say you're looking for the fastest...but do you have any
> memory limitations to be concerned about?
Single threaded. Might pass different blobs off to different threads to
be processed, but each blob would be parsed by a single thread. So no
concurrency concerns. The result of decoding might be handed off to
other threads to process.
Best analogy is writing a server in Java receiving binary encoded
packets. Need to decode packet read from a stream (socket), decode it,
do some work (one packet might be able to be spawned off into multiple
requests done by different threads), the formulate a response packet and
send it back. (I am not actually reading from a socket in my case - its
coming from files). But primary interest is decoding a packet. Also
interested now you mention it to build up a new packet to respond. But
it would be read and pull apart, or write and build up a new one (not
both at same time).
Someone wrote: about buf[i++] versus buf[++i]
I would hope the JRE would be able to optimize things so there is no
real difference here? For buf[++i] I would have to start i at -1, which
feels a bit funny. A loop looking for the end of the packet would also
be a bit strange (while (i + 1 < buf.length) instead of while (i <
buf.length)).
Rob wrote:
> Are each of the 4 groups of 8 bits likely to be signed? if not, you
> could perhaps 'or' together the first three, then perhaps only the
> last needs to be 'anded' with FF?
For a 32-bit integer, since its an array of byte (which is signed) you have to worry about the signed value for 3 of the 4 bytes. The most significant byte you don't have to worry about the sign of because the<<24 shifts the sign off the end of the integer (right fills with zeros). The<< operator upcasts the byte to integer before the shift occurs, which is when the sign extension occurs.
> I don't know where your getting your data from, but wonder whether 3/4
> of them are unsigned?
Its an arbitrary 32-bit integer, so when spliced into bytes I have no guarantee the individual bytes are signed or not.
> Certainly don't hold temporary variables inside the loop, the static
> method sounds better, although I don't know how many invocations will
> be made before it is in-lined; perhaps you should copy the code in-
> line to be sure?
Do you know that local variables inside a loop are slower? I would have assumed with all the cleverness of the JRE that would have been optimized out! I was hoping the&0xff would also be optimized out with the assembler using unsigned byte->int conversions (rather than signed extension functions).
Yes, I would rather use methods not repeat the code. Have to do the operation say a hundred times - certainly don't want to repeat the code all over the place!
Someone wrote: java.io.Bits
java.io.Bits! I did not know of that one, thanks. Will have a look. Hmm, seems to be doing pretty much the same thing as my code, but using offsets of +1, +2 etc instead of ++. Interesting... I never realized there was a>>> operator in Java! (Unsigned shift.) There is no<<< operator, but its not the shift that is an issue anyway - its the upcast from byte to int.
Fabrizio wrote:
> So, it's a matter of trying, measuring and re-measuring for each JRE update.
Hmmm. That is exactly what I was hoping NOT to hear!!!
Thanks everyone for comments!
Alan
On 7/22/10 09:53 , Alan Kent wrote:
>
> Fabrizio wrote:
>> So, it's a matter of trying, measuring and re-measuring for each
>> JRE update.
>
> Hmmm. That is exactly what I was hoping NOT to hear!!!
>
>
I know. :-) But one of the first things that I learned when I started
writing an image codec is that I needed performance testing
(automated, I mean). Then I understood I even need continuous
performance testing, as I discovered that some apparently minor
refactorings o my code could have an impact on performance. And as
it's usual for continuous practices, the point is to be aware of the
change as soon as possible, so you an track it down to the cause.
Forgot to say that my experience was also about very different
performance with different operating systems, but this wasn't due to
low level code as the one we're discussing about, rather to the
imaging libraries in the runtime, so it probably doesn't affect you.
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxH/ZMACgkQeDweFqgUGxf7aACfRSYjXG+I/2DpawbDtwwUBTjj
IP0AnjHjBVO7Tb5N64ueRwQqbjfL248Z
=vU5v
-----END PGP SIGNATURE-----
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
Van: viktor...@gmail.com [mailto:java...@googlegroups.com] Namens Viktor Klang
Verzonden: 22 July 2010 13:04
Aan: java...@googlegroups.com
Onderwerp: Re: [The Java Posse] Re: Fastest way to parse data out of array of bytes?
On 7/22/10 13:11 , Roel Spilker wrote:
> Maybe we should stop trying to give advice, apart from "Benchmark
> it in a real world scenario". The virtual calls could (and
> probably would) still be inlined if the VM can determine that it's
> possible. If not now, then probably in the next VM update.
>
Agreed. The point is that too many things are happening inside the VM,
and unless you're really a super expert (which means: you are Kirk
Pepperdine, one of the guys who write the C code inside the VM or at
least one who is able to read it) my impression is that any knowledge
about it is at least partially wrong or obsolete. Really, the least
risky strategy is to benchmark appropriately on a real world scenario.
Do that.
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
Fabrizio...@tidalwave.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxIKGoACgkQeDweFqgUGxdh7wCgh2OaLM8hg2gNK/Z27Vgjth3B
3DwAoLIMZ/3TWM+SOrh5pgDciznshsvX
=pSSX
-----END PGP SIGNATURE-----
Van: viktor...@gmail.com [mailto:java...@googlegroups.com] Namens Viktor Klang
Verzonden: 22 July 2010 13:04
Aan: java...@googlegroups.com
Onderwerp: Re: [The Java Posse] Re: Fastest way to parse data out of array of bytes?
Verzonden: 22 July 2010 13:21
Aan: java...@googlegroups.com
Onderwerp: Re: [The Java Posse] Re: Fastest way to parse data out of array of bytes?
On Thu, Jul 22, 2010 at 1:11 PM, Roel Spilker <R.Sp...@topdesk.com> wrote:
Maybe we should stop trying to give advice, apart from "Benchmark it in a real world scenario". The virtual calls could (and probably would) still be inlined if the VM can determine that it's possible. If not now, then probably in the next VM update.
Absolutely, however, how many Java devs are developing their software for future VMs?
In the future perhaps the entire code will be after-compiled by an artificial intelligence in the cloud...
What I listed are things that _today_ affect performance (if we're talking about millions of operations per second), not a look that gets completely unrolled.
There is merit to your words, but I think we should take a minute to reflect on the VMs that are out there, running code, today.
A lot of them are still on Java 1.4 or 5.
(1) Running in Eclipse using "Run" was about 3 times slower than running
"java" on command line (on my particular machine) on the same class
files. So yes, environment, JVM version etc make a BIG difference
straight up.
(2) If you want to write a class reading from a stream with a field
holding the current index being read from and you want to read 4 bytes,
its faster to update index once than updating 4 times.
class ByteBuf {
private int i = 0;
private byte[] buf = ...;
int slowerReadInt32() {
byte b1 = buf[i++];
byte b2 = buf[i++];
byte b3 = buf[i++];
byte b4 = buf[i++];
return (b1 << 24) | ((b2 & 0xff) << 16) | ((b3 & 0xff) <<
8) | (b4 & 0xff);
}
int fasterReadInt32() {
byte b1 = buf[i];
byte b2 = buf[i+1];
byte b3 = buf[i+2];
byte b4 = buf[i+3];
i += 4;
return (b1 << 24) | ((b2 & 0xff) << 16) | ((b3 & 0xff) <<
8) | (b4 & 0xff);
}
}
Upon reflection of course it will be faster. The first function has to
update the field 'i' per increment in case there is an index out of
bounds exception. The second only updates the field once.
Doing Google searches on Java vs C++ performance I found some Wikipedia
etc pages, that I don't trust much. There were a few subjective
sounding statements in there, and some comments talked about the new JIT
that might speed Java up. The only comments I almost trust were Java
probably does new/delete faster than C++ but tends to consume more
memory, and Java JIT might get code to same raw execution speed to same
as C++ (but 4 times slower is not unexpected).
So my next meaningless microbenchmark will be to try Scala with lazy
vals pulled from a byte[] (and so potentially avoiding the need for
converting bytes in a buffer into int's in the first place).
Alan
On 7/28/10 06:56 , Alan Kent wrote:
> In case anyone cares, did a bit of testing and found:
>
> (1) Running in Eclipse using "Run" was about 3 times slower than
> running "java" on command line (on my particular machine) on the
> same class files. So yes, environment, JVM version etc make a BIG
> difference straight up.
This sounds pretty strange, indeed.
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
Fabrizio...@tidalwave.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxPvjkACgkQeDweFqgUGxfQpgCgsIGwOLMrv4Bal0x30moNH8Eh
p9UAniJEnhGpaWd0YlzwrVVAdo2Tmc/c
=OTB7
-----END PGP SIGNATURE-----
Have you tried inlining those methods in your benchmark (no field references, as was mentioned -- just local variables).
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
On 7/28/10 20:02 , Casper Bang wrote:
>
> It's hard to know without your benchmarking suite, but it strikes
> me that the above, though unsafe, has a good chance of mapping to
> efficient native code.
BTW - if I'm not wrong, a few months ago Kohsuke blogged about
something related with the performance and by using some tool he
attached the generated native code (of course, at a given stage of the
run)... Am I wrong? Does such a tool exist? Or did I just dream about it?
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
Fabrizio...@tidalwave.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxQcxAACgkQeDweFqgUGxfeSQCfbB2m32lq0WpU2mBdOapkKv8X
DssAnR7R2A+oF52tSWW2A+MVc7KzmeZi
=D4mh
-----END PGP SIGNATURE-----
>
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 7/28/10 20:02 , Casper Bang wrote:
>>
>> It's hard to know without your benchmarking suite, but it strikes
>> me that the above, though unsafe, has a good chance of mapping to
>> efficient native code.
> BTW - if I'm not wrong, a few months ago Kohsuke blogged about
> something related with the performance and by using some tool he
> attached the generated native code (of course, at a given stage of the
> run)... Am I wrong? Does such a tool exist? Or did I just dream
> about it?
http://weblogs.java.net/blog/kohsuke/archive/2008/03/
deep_dive_into.html ?
>
> - --
> Fabrizio Giudici - Java Architect, Project Manager
> Tidalwave s.a.s. - "We make Java work. Everywhere."
> java.net/blog/fabriziogiudici - www.tidalwave.it/people
> Fabrizio...@tidalwave.it
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAkxQcxAACgkQeDweFqgUGxfeSQCfbB2m32lq0WpU2mBdOapkKv8X
> DssAnR7R2A+oF52tSWW2A+MVc7KzmeZi
> =D4mh
> -----END PGP SIGNATURE-----
>
> --
> You received this message because you are subscribed to the Google
> Groups "The Java Posse" group.
> To post to this group, send email to java...@googlegroups.com.
> To unsubscribe from this group, send email to javaposse+...@googlegroups.com
On 7/28/10 21:37 , Stuart McCulloch wrote:
>>
> http://weblogs.java.net/blog/kohsuke/archive/2008/03/deep_dive_into.html
That's
>
it.
PS My sense of time is getting completely distorted. I believed it was
only a few months ago, and it was more than two years!
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
Fabrizio...@tidalwave.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxQj/QACgkQeDweFqgUGxe7EgCffvautmkDY1tWd5hWN2sG+mRZ
HukAniM+eRbuElfQJfXb6Ns95zn8oZaO
=j0kf
-----END PGP SIGNATURE-----
Agreed completely. Microbenchmarks are interesting, but dangerous to
rely on. It was a loop run 100,000,000 times so I would have hoped the
JIT would have jumped in, but it is one small part of an overall problem.
I have a choice between writing something in C++ or Java (maybe Scala if
I can swing it). My take on the state of the universe is C++ is safer
from a performance perspective (for my project which has high throughput
requirements), Java is safer from a speed of code development and
maintainability perspective. I don't need lots of memory allocations,
so the GC benefits of Java are not relevant. Java also has issues being
a less friendly citizen on a box shared with other processes (more
memory hungry).
But thanks Casper, sun.misc.Unsafe was an interesting find that I never
knew about!
Thanks to everyone else for contributions. Interesting stuff.
Alan
On 7/29/10 07:47 , Alan Kent wrote:
> On 29/07/2010 3:05 PM, Reinier Zwitserloot wrote:
>> That's not to say what you're doing is at all useful, really.
>> You can't microbenchmark code for the JVM. End of discussion.
>> Stop doing it.
>>
>
> Agreed completely. Microbenchmarks are interesting, but dangerous
> to rely on. It was a loop run 100,000,000 times so I would have
> hoped the JIT would have jumped in, but it is one small part of an
> overall problem.
Agreed on the uselessness of microbenchmarking. My point with the
- -XX:Print... stuff is that it should at least solve some common doubts
such as "the code should be inlined" etc... that are recurring and
seems to be never solved by a discussion.
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxRGaQACgkQeDweFqgUGxdp8wCfYQ3FjDJJtuokRT7RsjfiOXfd
1fwAn1uRcY1GlQvvZIuARCIZ7QvfpnD9
=qjRW
-----END PGP SIGNATURE-----
I can show you plenty of problems where the language of implementation can never be an issue w.r.t. performance. Choosing a language based on "performance safeness" is the ultimate premature optimization. There are just so many other factors that need to be considered.
Regards,
Kirk
Just a bit of back fill (happy for this thread to die off now) - I had
some raw C struct like data in an array of bytes. I am trying to put
forward a case for using Java (or maybe Scala) instead of C/C++ in a
project. Performance is critical. In C/C++, one argument is you can
cast the pointeer to the array of bytes and volia! you can access all
the int's etc. Very performant. Obviously cannot do this in Java, so
was trying to work out how close I could get Java to squash this
argument (if possible). Obviously the overall application makes a big
difference too. Right now C++ is safe from a performance perspective,
Java safer from a code maintainability perspective. There is a hard
performance requirement on the project (harder than the code
maintainability requirement).
Thanks
Alan
>> My instinct tells me that this is yet another naive attempt at benchmarking....
>
> But if Alan identified a performance trouble area, then surely he's
> can't do anything else than what he is doing... trial-n-error under
> simulated conditions (acceptance tests). We can't all be Brian Goetz
> and walking around with intricate detail of the internals of the JVM.
Nonsense.. :-) You may not understand what is going on but that doesn't mean it's not deterministic, very very deterministic. One doesn't need to have all the internal details of the JVM to write a decent benchmark. You just need to know a few simple concepts. There is a profiler that execution model or our application. When a portion of the model is properly developed, the profiler tells the JIT to compile the code. In the process, it looks for common patterns in the execution model that it can optimize. Optimizations often involve a reorganization of the code. Do I know what those patterns are? Nope! Do I care? I might but.... often I don't. I just want it to happen and I want to make sure that I'm making measurements when it's all done. But that's common with every bench... I want to work through the startup phase before I measure. To do that I can tell the JIT to log compilation. If the JIT stops logging, you're finished warming up and it's time to measure. If I *need* to know how the JIT has treated my code, I'll ask the it to dump assembler. If you don't know how to do these things, you need to investigate and learn (like Brian has) or you simply shouldn't be benchmarking. And thats ok, benchmarking is not for everyone. I don't write GUI code and probably never should ;-)
I wouldn't use Unsafe but for corner cases in specific instances. However one could use AtomicReference which uses Unsafe or the equivalent in other environments. But that's typically not so easy so you're right, there is no spoon.
Regards,
Kirk
Regards,
Kirk
Roel
> -----Oorspronkelijk bericht-----
> Van: kirk.pe...@gmail.com
> [mailto:java...@googlegroups.com] Namens Kirk
> Verzonden: 29 July 2010 10:19
> Aan: java...@googlegroups.com
> Onderwerp: Re: [The Java Posse] Bad benchmarks was fastest
> way to parse
This isn't my experience.. I've found HotSpot to be very predictable. Case in point, I recently helped a client diagnose a luke-warm method problem related to hotspot compilation. We were able to completely predict if and when a key method would be compiled along with how it would be compiled. The effect that Josh is talking about is common when the execution profile changes over time. HotSpot decompiles, remeasures and then recompiles.
One other point, microbenchmarking almost always involves creating code that confuses HotSpot so that it cannot apply the optimizations that would normally be applied. IOWs, it's not production code and the effects in production may be different than those found in the benchmark.
To Josh's point, figuring out when these changes may happen isn't easy but it's not impossible.
Regards,
Kirk
On 7/29/10 11:37 , Casper Bang wrote:
> I'll still claim it's non-deterministic, you can not possibly know
> certain aspects of the hardware (word length, branch predictor,
> hyper- treading/pipeline-swap support, CAS-support etc.) and
> software (which gen an object is in, what will be inlined, which
> compacting strategy, where there are safe-points, context-switches
> and write-barriers).
>
> Don't get me wrong, that's the wonder of the JVM/JIT. But
> sometimes it would be nice to be able to just rely on AOT
> compilation so you'd truly know what you are getting. Btw. I never
> really understood why the JVM doesn't just cache an already JIT'ed
> memory image which can then just be loaded next time without
> verifier and profiler running, especially when running stuff in
> client-mode.
Let me give my interpretation, as a totally non-expert of JIT. Even if
it's deterministic, it is in controlled conditions (the microbenchmark
context). In the real world, a lot of different things will happen at
the same time, and determinism goes away. Still, I find that the JIT
native code dump could be useful for guessing the upper bound, in some
cases. I mean, if you have to compute a FFT and are discussing with a
C/C++ guy, it would be nice to see the dump. If it's comparable with
the C/C++ code, you could tell the C/C++ guys that, at least in
optimal cases, there are no big differences (this is already a strong
point in a discussion, as still many people completely lacking the JIT
culture don't get the point). So, at this point it makes sense a
broader-horizon benchmark. If the code is much worse than C/C++, you
already know that you'll have a possible performance hit in that
section and would probably make sense to evaluate, together with all
the other requirements and constraints, to use native code or such. I
would run a broader-horizon benchmark all the same, but probably spend
less time with it. I
mean, I expect that there will be cases in which the code is good and
other in which isn't, and that could be an architectural hint.
Furthermore, it would be interesting to repeat the same comparison
after an upgrade of the runtime, e.g. when they say that there are JIT
improvements. Maybe you discover that the code in the optimistic
scenario has improved since the past and you can change your mind.
- --
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxRUlYACgkQeDweFqgUGxenWwCdF82gU3Z94avvYjmxb0Pnt7Eh
MLoAn2qh8IlwU8WvqJtc8aUzx30SnocE
=pvdD
-----END PGP SIGNATURE-----
I can only base it on one personal mid-sized program that I have done
myself (involving lots of XML parsing in Java and C++) which went around
10 times faster in C++ (a year or two back), and articles I can find
doing Google searches. Anyone who has concrete info would be great.
But it really needs the same program implemented in Java and C++ to do
direct comparisons. Some of the articles have so much subjective
sounding text in them I simply do not believe them. (One more
realisitic one involved was I think Quake being ported to Java and
performing just as well - but I don't know if most of the time is really
spent in the GPU rather than Java itself.)
Based on personal experience (10+ years of C++ programming and 5+ years
of Java programming), the discussions I have had writing performant C++
code involve talking about memory alignment, cache lines, avoiding
memory copies, templating, inlining, looking at the resultant assembler
etc. You can write multiple classes in C++, then use them to build up a
more complex data structure where the whole structure takes a single
malloc to create. Java if you use multiple classes you get multiple
memory allocations (one per object instance). In C++ I can write an
array of classes (or structs) and all the objects are inlined in the
array - in Java I have to have an array of references to objects, with a
new object for each value in the array. In writing Java you don't have
the sort of control as in C++. However in Java memory management is
cheaper (if you have the same number of mallocs!). In one large
(multi-million line C++ code) multi-threaded program, we found changing
the memory allocation library had a 20% difference (or more) in overall
performance. No other change the C++ code - just link in a different
malloc library and major difference in performance. We have had to
worry about things like which threads data structures were allocated
from as the malloc library had a pool per thread. If a different thread
ends up doing the frees, you end up with lots more lock contention in
the malloc library.
I don't want to get carried away here (its all been said before and I
did not mean to start Yet Another Language War), but I have read on the
web numerous opinions (not much evidence) saying Java can generate code
around the same performance as C++ code. I have never seen anything I
trust saying it can be much faster. I have heard (and experienced)
cases where its definitely much slower. I have heard many people I
trust in different forums all say C++ code executes faster - use it when
you want to control performance. Its backed up by personal experience.
I have not heard of significant sized projects where Java saved the day
over C++ in terms of performance (that are backed by believable
evidence). What I do believe is Java is much more productive for
programmers, pretty good in performance, and does have harder to measure
benefits in the more modern garbage collectors that only come up when
you have a large running system. Talk to our sysadm admins about Java
and they want to know if anything else needs to run on the same box as
if you have a few Java processes memory consumption goes through the
roof (compared to equivalent C/C++ programs) - making it harder to share
a box without problems. Not trying to be argumentative here, but I have
not seen any evidence that can change my mental model of Java = easier
to write and maintain, C++ = higher performance. (I guess I should add
C# = Microsoft.)
Final word in micro benchmarks, I know their limitiations (have done
lots of performance analysis over the years), but in the words of
Charles Babbage http://en.wikipedia.org/wiki/Charles_Babbage "Errors
using inadequate data are much less than those using no data at all".
Thanks all!
Alan
your ability to measure the performance of C/C++ and Java integration
might also be worth looking at..
Which is the best way to implement pointer-like functionalities in pure java..?
I like this concept, but java is not meant for all this..its more
distributed & network oriented rather than machine/memory functions
handling ..
jd
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
I'll still claim it's non-deterministic, you can not possibly know
certain aspects of the hardware (word length, branch predictor, hyper-
treading/pipeline-swap support, CAS-support etc.) and software (which
gen an object is in, what will be inlined, which compacting strategy,
where there are safe-points, context-switches and write-barriers).
Don't get me wrong, that's the wonder of the JVM/JIT. But sometimes it
would be nice to be able to just rely on AOT compilation so you'd
truly know what you are getting. Btw. I never really understood why
the JVM doesn't just cache an already JIT'ed memory image which can
then just be loaded next time without verifier and profiler running,
especially when running stuff in client-mode.
/Casper
On Jul 29, 10:58 am, Kirk <kirk.pepperd...@gmail.com> wrote:
> On Jul 29, 2010, at 10:45 AM, Ben Schulz wrote:
>
> > On 29 Jul., 10:15, Kirk <kirk.pepperd...@gmail.com> wrote:
> >> Nonsense.. :-) You may not understand what is going on but that doesn't mean it's not deterministic, very very deterministic.
> > A small excerpt from Josh Bloch's "Mind the Semantic Gap"[1]:
> >> [W]hen it does come time to optimize, the process is greatly complicated by the semantic gap. Consider this: Suppose you carefully write a well-designed microbenchmark that does everything right (e.g., warms up the VM, ensures that computation is not optimized away, times a sufficient amount of computation, does multiple timings to ensure repeatability). You run the benchmark, and see that after warmup, every run takes nearly the same amount of time. Happiness? You run the benchmark again, and again every run takes the same amount of time, but it's a different amount! You run the program twenty times, and see the results clustering into several groups, but always consistent within a program-run. What is going on?
>
> >> In modern VMs such as HotSpot, the task of deciding what to inline and when to inline it is performed by a background thread (at runtime). This process is called "compilation planning." Because it's multithreaded, it's nondeterministic.
>
> This isn't my experience.. I've found HotSpot to be very predictable. Case in point, I recently helped a client diagnose a luke-warm method problem related to hotspot compilation. We were able to completely predict if and when a key method would be compiled along with how it would be compiled. The effect that Josh is talking about is common when the execution profile changes over time. HotSpot decompiles, remeasures and then recompiles.
>
> One other point, microbenchmarking almost always involves creating code that confuses HotSpot so that it cannot apply the optimizations that would normally be applied. IOWs, it's not production code and the effects in production may be different than those found in the benchmark.
>
> To Josh's point, figuring out when these changes may happen isn't easy but it's not impossible.
>
> Regards,
> Kirk
--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
have a look at this too...
jd
>> javaposse+...@googlegroups.com<javaposse%2Bunsu...@googlegroups.com>
As for micro benchmarks, I've seem some really bad stuff done in the name of micro benchmarking and so I'm not sure that Mr. Babbage's great quote applies. He lived in a much different world than we do today ;-)
Regards,
Kirk