Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Limit JNI calls in nativeUpdateMarker #5103

Closed
tobrun opened this issue May 23, 2016 · 2 comments
Closed

Limit JNI calls in nativeUpdateMarker #5103

tobrun opened this issue May 23, 2016 · 2 comments
Labels
Android Mapbox Maps SDK for Android performance Speed, stability, CPU usage, memory usage, or power usage refactor

Comments

@tobrun
Copy link
Member

tobrun commented May 23, 2016

In jni.cpp we have a method nativeUpdateMarker. This method is used to update the position and icon of a Marker. Currently the method looks like:

void nativeUpdateMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* marker) {
    mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdateMarker");
    assert(nativeMapViewPtr != 0);
    NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);

    jlong markerId = jni::GetField<jlong>(*env, marker, *markerIdId);
    if (markerId == -1) {
        return;
    }

    jni::jobject* position = jni::GetField<jni::jobject*>(*env, marker, *markerPositionId);
    jni::jobject* icon = jni::GetField<jni::jobject*>(*env, marker, *markerIconId);

    jni::jstring* jid = reinterpret_cast<jni::jstring*>(jni::GetField<jni::jobject*>(*env, icon, *iconIdId));
    std::string iconId = std_string_from_jstring(env, jid);

    jdouble latitude = jni::GetField<jdouble>(*env, position, *latLngLatitudeId);
    jdouble longitude = jni::GetField<jdouble>(*env, position, *latLngLongitudeId);

    // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long.
    nativeMapView->getMap().updatePointAnnotation(markerId, mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), iconId));
}

Following the guidelines related to JNI and mentioned in the Google I/O session related to NDK, we should limit the amount of JNI calls inside one JNI method. In case from above this would result in removing the jni::GetField items and replacing jobject marker with multiple parameters.

For example this will result in replacing the following in the method signature:

jobject marker -> jdouble lat, jdouble lon, jstring iconId
@tobrun tobrun added refactor Android Mapbox Maps SDK for Android performance Speed, stability, CPU usage, memory usage, or power usage labels May 23, 2016
@tobrun
Copy link
Member Author

tobrun commented May 23, 2016

I have been doing some profiling on this.

As-is

Here you can see the as-is situation. The top level selected method is animateValue and is called by the animator framework to update the position of the marker.

screen shot 2016-05-24 at 00 29 22

With the as-is situation 81.2 % is allocated to call setPosition and 3.5% is used for calculateValue.

Proposed improvement

Here you can see the proposed alternative. You can see the same method selected as above only this time it's calling the suggested improvement mentioned in OP.

screen shot 2016-05-24 at 00 30 05

With the proposed solution 58.7 % is allocated to call setPosition while 32.8% is used for calculateValue. This means we have decreased the execution time in relation with calculateValue dramatically.

Putting both methods side-by-side in one execution. Shows the idea behind the OP:

screen shot 2016-05-24 at 00 37 50

You can see that the as-is situation results in 26 method calls, while the suggested solution results in 4.

@bleege
Copy link
Contributor

bleege commented Jun 9, 2016

Looks like this particular case, nativeUpdateMarker, was done in #5076 and then again in #5303.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android performance Speed, stability, CPU usage, memory usage, or power usage refactor
Projects
None yet
Development

No branches or pull requests

2 participants