On 25 March 2014 19:59, Joachim Geidel <joachim.gei...@onlinehome.de> wrote:

> Hi everybody,
>
> JNIPort for Pharo 3.0 alpha is now available at SmalltalkHub.
>
> JNIPort is a Smalltalk library which allows Java code to be invoked from
> Smalltalk. It acts as a bridge between the world of Smalltalk objects and a
> Java Virtual Machine (JVM) where Java code is executing.
>
> When I first ported JNIPort to Squeak and Pharo 1.x, I used Alien as the
> FFI
> library. As NativeBoost has superseded Alien, the interface to the Java
> Native Interface library had to be rewritten. There are still some
> undocumented and obscure parts in NativeBoost, so this has taken some time.
>
> If you want to try it, load it via the ConfigurationOfJNIPort. I hope this
> works. If it does not, load the packages individually in the order in which
> they appear in the ConfigurationOfJNIPort.
>         http://www.smalltalkhub.com/#!/~JNIPort/JNIPort
> The next step is to read the documentation at
>         http://jniport.wikispaces.com/
> Otherwise, you won't know what to do next. ;-)
> Download the extra files from the download page at Wikispaces, you will
> need
> two jar files from there.
>
> Start a Java VM attached to Pharo by adapting and executing the following
> code snippet:
>
> ----
> | jvmSettings |
>  "You can set the path to the Java VM library by editing the path as
> needed."
> JNIPortJNIInterface libraryFile:
>
> '/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries/libclient.dylib'
> .
> "JNIPortJNIInterface libraryFile:
> 'C:\Programme\Java\jre7\bin\client\jvm.dll' ."
>
>  jvmSettings := JVMSettings new.
>  jvmSettings usesGhosts: true.
>  jvmSettings supportsCallbacks: true.
>  jvmSettings jniPortSettings  useJNIHelperLibrary: false.
> jvmSettings ghostClassSettings retainMethodSource: true.
>
>  "On Mac OS X and Linux, class path entries are separated by colons."
>  "On Windows, you have to use semicolons instead. Edit the following line
> as
> needed."
> jvmSettings runtimeSettings classpath:
> '.:/Users/myname/JNIPort.jar:/Users/myname/JNIPort-Tests.jar'.
> " jvmSettings runtimeSettings classpath:
> '.;.\JNIPort.jar;.\JNIPort-Tests.jar'."
>
>  "Uncomment the following if you want the Java VM to emit verbose messages.
>   How to access these messages depends on your platform.
>   On Mac OS X, they are visible in the Console application."
> "jvmSettings runtimeSettings addOption: '-verbose:jni'; addOption:
> '-verbose:gc'; addOption: '-verbose:class'."
> Cursor execute showWhile: [JVM newWithSettings: jvmSettings].
> ----
>
> Then the fun starts:
>
> ----
> | zfClass zipfile entries |
> zfClass := JVM current findClass: #'java.util.zip.ZipFile'.
> zipfile := zfClass new_String: 'JNIPort.jar'.
> zipfile size. "--> answers an Integer"
> entries := zipfile entries.
> entries asAnEnumeration do: [:each | Transcript cr; print: each].
> ----
>
> And now to the ugly little secret reason why I call it an alpha version:
>
> While everything seems to work, it is *much* slower than it used to be in
> Pharo 1.2 with Alien. And when I compare it with VisualWorks, I wonder if
> the Pharo version secretly does some additional work for SETI:
> - Starting the JVM:
>         VisualWorks 0.7 seconds
>         Pharo 7 to 8 seconds
> - A benchmark using some methods of java.io.BufferedReader and
> java.util.StringTokenizer:
>         VisualWorks 114 milliseconds
>         Pharo 12 to 13 seconds
>
>
profiled a bit.. this:
===================
| jvmSettings |
 "You can set the path to the Java VM library by editing the path as
needed."
JNIPortJNIInterface libraryFile:
'/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries/libclient.dylib'
.
"JNIPortJNIInterface libraryFile:
'C:\Programme\Java\jre7\bin\client\jvm.dll' ."

 jvmSettings := JVMSettings new.
 jvmSettings usesGhosts: true.
 jvmSettings supportsCallbacks: true.
 jvmSettings jniPortSettings  useJNIHelperLibrary: false.
jvmSettings ghostClassSettings retainMethodSource: true.

JVM newWithSettings: jvmSettings
==============
and got this:

**Leaves**
22.8% {925ms} StaticJavaLangClassLoader(JavaStatic)>>knownJavaSubclasses
19.9% {804ms} JVMWithCallbacks(JVM)>>findClassFor:
5.9% {240ms} OrderedCollection>>do:
5.1% {206ms} Metaclass(Behavior)>>registerLocalSelector:
3.0% {120ms} JNIPortJNIEnv>>return:onException:
2.2% {91ms} CompiledMethod>>methodClass:
2.2% {88ms} OrderedCollection>>add:
2.1% {84ms} Array(SequenceableCollection)>>do:
2.0% {81ms} WordArray class(Behavior)>>new:
2.0% {79ms} WeakArray class>>finalizationProcess
1.3% {52ms}
JNIPortJNIInterfaceForMacOSX(JNIPortJNIInterface)>>checkReturnCode:
1.1% {46ms} Heap>>updateObjectIndex:

-------------
findClassFor: aJNIObject
    "private -- find/make the JavaStatic that will wrap aJNIObject"

    "we have to ensure that the ref is converted to global if necessary
*before* the class
    lookup, since that might take considerable time during which callbacks
might happen
    (especially if new ghost classes have to be constructed).
    Hence we convert it now, even though we will 'convert' again later (in
#own:)"

    "NB: this will #become: the JNIObject into a global ref if necessary"
    self convertToGlobal: aJNIObject.

    ^ super findClassFor: aJNIObject.
----------

so, without going deep into implementation details, just by reading comment
i can already see potential bottleneck - using #become: operation which is
veery slow.

also, by tracking senders of #knownJavaSubclasses , i see there's also uses
of #become operation..

So, my first verdict is:
       - excessive use of #become ==> slow performance
:)

(sure, i have no idea if you can avoid using become or not, but my bet
this  is main reason of low performance)

-- 
Best regards,
Igor Stasenko.

Reply via email to