0

In another post, I talk about the need for support of primitive array in javonet. Could this explain why pulling ~2GB worth of double array is about 10x slower than comparable code in .net? I've attached a screenshot of JProfiler in case it helps. (Also, though not shown, JProfiler also showed about 1GB of Double objects, which I think should not exist if we just had primitives; but, is this the reason for the slowness or is it because of the ~40,000 calls to a .net method, and all the "stuff" in between with Javonet etc end up taking a few hundred miliseconds or so?)

JProfiler hostspot view

UPDATE 5/3/2018:

If you read the comments to the first response, you'll eventually see a build (hf16) which resolves the slowness problem. Javonet appears quite fast....I imagine that this build will eventually make it into the core product.

Jonathan Sylvester
  • 1,275
  • 10
  • 23
  • Hi Jonathan, I see you have 897 calls of sendCommandBinary what means you call .NET 897 times not 40k. Is the screenshot not showing your entire run or maybe by accident you mistakenly took the number of ms which is indeed around 40k? – Przemysław Ładyński Apr 28 '18 at 19:39
  • Anyway we have answered to your other thread so let us know if using primitives improves your results. That would be visible especially if you retrieve 2Gb array in one call. For multiple calls there is still space for improvement in terms of the unnecessary forwarding method name with each call what we mentioned in other thread: https://stackoverflow.com/questions/50063124/performance-of-javonet/50063763#50063763 we will address that and provide you another build for testing in this thread. – Przemysław Ładyński Apr 28 '18 at 19:41
  • I edited the post to point everyone to the comments in the first response, as the latest build (hf16) is very very fast (ie problem seems to be resolved.) – Jonathan Sylvester May 03 '18 at 16:49

1 Answers1

0

Jonathan, deeply analyzing your case the answer to your performance issues comes from variety of factors. Let me explain them one by one:

  1. Boxing/Unboxing - indeed this had an impact on your results, as answered in this thread How to avoid autoboxing of primitives in arrays in javonet there is beta release which includes ability to force Javonet to use primitive arrays as result. So this issue can be resolved easily.
  2. Unnecessary Strings Passed as mentioned here Performance of Javonet current release of Javonet for Java developers is still suffering from an issue that even for optimized subsequent method calls the method name was passed to .NET side and converted to .NET string. Moreover for each result the type name was returned and converted to Java string. This has been resolved in Javonet for .NET developers already. We addressed this issue for you in temporary build merging those optimizations into Javonet for Java developers. (link below).
  3. Data Type Conversion analyzing your results we found out an issue in "double" processing that might have affected your performance. This is also covered in temporary build linked below.
  4. Type of Operation for Javonet the most costly operation is the on the fly conversion of value-types. Depending on time its either superfast (i.e. boolean) or quite costly (i.e. UInt64). So your case is special as you do few cross-boundry calls but you do a lot of value-type conversion (2GB of array). Completely different results you should observe if you compare calling many times (i.e. 250k) method generating prime number for growing "x" argument. (if you compare that to calling same method via web services i will be 1000x faster)
  5. Way of Comparing Results lastly but very important is that Javonet performance varies depending on the operation you do and way you compare the results. It's clear that if you invoke a method which does nothing purely in .NET it will be optimized by compiler and execute in almost "no time". When you call it through Javonet it will take some "tiny" time (i.e. 0.0000009s) to pass the call to .NET. In result when you divide "tiny" by "no time" it is like dividing 10 by 0 so you could assume its infinitly slower (does it mean Javonet is slow? - not exactly). However if you call a method which does some processing or retrieves data from DB etc.. then Javonet overhead will be almost unoticable.

Unstable beta release with fix for faulty string exchange and double data type conversion: ...link removed due to newer release included in update below...

Please use this only for measuring purposes. We would be happy to know your results. Soon those changes will be merged in stable state to official build and we will inform you afterwards.

Summarizing: There are different reasons for the performance results you obtain. Some of them are being addressed by beta patch mentioned above, some are related to the way you measure and operation you do. Javonet in many cases is the fastest native integration technology between .NET and Java, as recognized in tests of many our customers and trusted in solutions like high frequency trading, real-time data processing, controlling manufacturing and medical devices and other... Of course there are still situations and cases where performance varies. Achieving highest results is one of our key priorities, following one of our principles "be faster with each release". We always accept performance challenges of our customers implementing on-demand improvements if needed. We do accept yours and will strive to optimize for big primitive arrays retrieval as well.

Please test the patch above which should expose significant improvement but still will suffer from environmental reasons points: 4 and 5.

Update 2018-04-30: We have started the implementation of modernized optimization module to address scenarios like yours preserving highest possible performance almost equal to native. Under link below you will find alpha release which works in "usePrimitiveArraysMode" for non-generic methods returning "double[]" without ref/out arguments. I.e. double[] CreateArray() or double[] CreateArray(int size) etc...

http://download.javonet.com/1.5/javonet-1.5hf15-primitivearrays-opti-jtdn.jar

  • This last link works, but the one before it does NOT (we get runtime failures etc). It should probably be removed so that future readers see only the working last link.... – Jonathan Sylvester Apr 30 '18 at 15:28
  • Thanks! Updated. It was unstable build and some operations might have caused the crash. The HF15 passed basic testing route so should be much more reliable. We plan to release official update with that new approach in ~2 weeks. – Przemysław Ładyński Apr 30 '18 at 15:35
  • @JonathanSylvester in HF15 the optimization will work only on the subsequent calls of them method on the same instance, we will move it to type scope in next build. To get representative results please run target method once before the measuring loop. It will let you get representative results even on very short / small tests. – Przemysław Ładyński Apr 30 '18 at 16:12
  • This is probably a dumb question, but in my case, the inner loop is of size 1250 and the outer loop is of size ~20, so in total, we're invoking a javonet method approx 1250*20 = 25000 times, so I shouldn't need to "call it once as a warmup", since the effect of the (slower) first invocation is neglibile when averaging over 25,000 calls, right? – Jonathan Sylvester Apr 30 '18 at 20:05
  • Correct, it's important if you make tests on small number of calls in such case it might be significant. However even if it is negligible in final release we will strongly optimize that "warmup" part so if you want to have the feeling of final outcome its good to make it before. Can you let us know if you work on one or more instances, and what are the signatures of methods you call in your loops? – Przemysław Ładyński Apr 30 '18 at 20:09
  • What do you mean by "one or more instances"? If you mean "does the object change" in every loop, the answer is yes. The method is still the same that gets called; but, it's a different object. Would that explain why one of my developer's native JNI logic (he used C++/SWIG/Java) is about ~7x to ~8x faster than the current 1.5hf15 build of javonet? – Jonathan Sylvester May 01 '18 at 01:58
  • Yes, we will provide the hf16 today which optimizes on the scope of type not instance. We will update you here shortly. – Przemysław Ładyński May 01 '18 at 06:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/170159/discussion-between-jonathan-sylvester-and-przemyslaw-ladynski). – Jonathan Sylvester May 01 '18 at 17:09