Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

JNI call seem to be very slow

843829Sep 15 2009 — edited Sep 16 2009
Hello,

I have an optimized JPEG decoder written in C++, I have a JNI bridge to that codebase with this method:

Java-side:
public static native byte[] readJPEG(String name);
C++ side:
JNIEXPORT const jbyteArray JNICALL Java_IPPJPEGDecoder_readJPEG(JNIEnv *, jclass, jstring);
I have this call in Java layer:
long start = System.currentTimeMillis();

byte[] data = IPPJPEGDecoder.readJPEG("C:\\D-102_red_ink_1.JPG");

long end = System.currentTimeMillis();

System.out.println("total time = " + (end - start));
This is my method in C++ (rough/ugly code, don't judge me :) )
JNIEXPORT const jbyteArray JNICALL Java_IPPJPEGDecoder_readJPEG (JNIEnv * env, jclass jobj, jstring jpeg_filename)
{
    //cout << "INVOKED IPPJPEGDecoder.readJPEG() SUCCESSFULL" << endl;
    //cout << "Started"<<endl;
    CIppImage m_image;
    CIppImage grayscale_image;
    CIppImage monochrome_image;
    CTimer timer;
    timer.Start();
    CStdFileInput in;
    const IppLibraryVersion* libver = ippGetLibVersion();
    cout << "LibraryVersion = (" << libver->Name <<": " << libver->Version << ")"<<endl;
    UIC::BaseStream::TStatus status;
    jboolean iscopy;
    const char * filename = env->GetStringUTFChars(jpeg_filename,&iscopy);
    status = in.Open(filename);
    GetImageFromJPEGJNI(in, m_image, timer);
    cout<<"m_image: (Precision: " << m_image.Precision() << ", NumChannels: " <<m_image.NChannels()<<", Width: " << m_image.Width() << ", Height: " << m_image.Height()<< ", Color: " << m_image.Color() <<", step: " << m_image.Step()<<endl;
    timer.Start();
    cout << "data array size of image : " <<(m_image.Step()*m_image.Height())<<endl;
    jbyteArray jb = env->NewByteArray(m_image.Step()*m_image.Height());
    env->SetByteArrayRegion(jb,0, m_image.Step()*m_image.Height(),(const jbyte*)m_image.DataPtr());
    timer.Stop();
    double mytime = timer.GetTime();
    cout << "JNI occurred in " << mytime << " ms"<<endl;
    return jb;
    //return NULL;
}
When I call this code, the C++ codeblock reports as running in 92.7793 ms

My java code reports back: 572 ms

is the Call to the JNI method THAT INSANELY slow !?!?! I MUST be doing something wrong... this is in Windows XP and I'm linking against my own dll that I compiled in Microsoft Visual C++ 2008.

The jbyteArray that I'm passing back has a length of 33583500
... maybe it's the conversion from jbyteArray to Java's byte[] that is causing all the overhead.... are there any ways around that?

Thanks!!

Alessandro Ferrucci
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 14 2009
Added on Sep 15 2009
9 comments
910 views