diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java index 5f88ba851..e195ea62c 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java @@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.testapp; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Debug; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; @@ -47,7 +48,7 @@ public class BulkMarkerActivity extends AppCompatActivity { mMapView.onCreate(savedInstanceState); mMapView.setCenterCoordinate(new LatLngZoom(38.87031, -77.00897, 10)); - new LoadBulkMarkerTask(mMapView, 1000).execute(); + new LoadBulkMarkerTask(mMapView, 27267).execute(); } @Override @@ -118,11 +119,21 @@ public class BulkMarkerActivity extends AppCompatActivity { @Override protected List doInBackground(Void... params) { - List markerOptions = new ArrayList<>(); + //Debug.startMethodTracing("bulk-marker"); + TimingLogger timings = new TimingLogger(TAG, "doInBackground"); + //Log.d(TAG, "isLoggable " + Log.isLoggable(TAG, Log.VERBOSE)); + + List markerOptions = new ArrayList<>(mAmount); + timings.addSplit("create ArrayList"); + try { DecimalFormat formatter = new DecimalFormat("#.#####"); + String json = Util.loadStringFromAssets(mAppContext, "points.geojson"); + timings.addSplit("loadStringFromAssets"); + List locations = Util.parseGeoJSONCoordinates(json); + timings.addSplit("parseGeoJSONCoordinates"); LatLng location; for (int i = 0; i < mAmount; i++) { @@ -132,20 +143,30 @@ public class BulkMarkerActivity extends AppCompatActivity { .title("Marker") .snippet(formatter.format(location.getLatitude()) + ", " + formatter.format(location.getLongitude()))); } + timings.addSplit("create all MarkerOptions"); + } catch (IOException | JSONException e) { Log.e(TAG, "Could not add markers,", e); } + + timings.dumpToLog(); return markerOptions; } @Override protected void onPostExecute(List markerOptions) { super.onPostExecute(markerOptions); + TimingLogger timings = new TimingLogger(TAG, "onPostExecute"); + MapView mapView = mMapView.get(); if (mapView != null) { List markers = mapView.addMarkers(markerOptions); Log.v(TAG, "Markers added " + markers.size()); } + timings.addSplit("addMarkers"); + + timings.dumpToLog(); + //Debug.stopMethodTracing(); } } } \ No newline at end of file diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TimingLogger.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TimingLogger.java new file mode 100644 index 000000000..de8c4df30 --- /dev/null +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TimingLogger.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mapbox.mapboxsdk.testapp; + +import java.util.ArrayList; + +import android.os.SystemClock; +import android.util.Log; + +/** + * A utility class to help log timings splits throughout a method call. + * Typical usage is: + *

+ *

+ *     TimingLogger timings = new TimingLogger(TAG, "methodA");
+ *     // ... do some work A ...
+ *     timings.addSplit("work A");
+ *     // ... do some work B ...
+ *     timings.addSplit("work B");
+ *     // ... do some work C ...
+ *     timings.addSplit("work C");
+ *     timings.dumpToLog();
+ * 
+ *

+ *

The dumpToLog call would add the following to the log:

+ *

+ *

+ *     D/TAG     ( 3459): methodA: begin
+ *     D/TAG     ( 3459): methodA:      9 ms, work A
+ *     D/TAG     ( 3459): methodA:      1 ms, work B
+ *     D/TAG     ( 3459): methodA:      6 ms, work C
+ *     D/TAG     ( 3459): methodA: end, 16 ms
+ * 
+ */ +public class TimingLogger { + /** + * The Log tag to use for checking Log.isLoggable and for + * logging the timings. + */ + private String mTag; + /** + * A label to be included in every log. + */ + private String mLabel; + /** + * Used to track whether Log.isLoggable was enabled at reset time. + */ + private boolean mDisabled; + /** + * Stores the time of each split. + */ + ArrayList mSplits; + /** + * Stores the labels for each split. + */ + ArrayList mSplitLabels; + + /** + * Create and initialize a TimingLogger object that will log using + * the specific tag. If the Log.isLoggable is not enabled to at + * least the Log.VERBOSE level for that tag at creation time then + * the addSplit and dumpToLog call will do nothing. + * + * @param tag the log tag to use while logging the timings + * @param label a string to be displayed with each log + */ + public TimingLogger(String tag, String label) { + reset(tag, label); + } + + /** + * Clear and initialize a TimingLogger object that will log using + * the specific tag. If the Log.isLoggable is not enabled to at + * least the Log.VERBOSE level for that tag at creation time then + * the addSplit and dumpToLog call will do nothing. + * + * @param tag the log tag to use while logging the timings + * @param label a string to be displayed with each log + */ + public void reset(String tag, String label) { + mTag = tag; + mLabel = label; + reset(); + } + + /** + * Clear and initialize a TimingLogger object that will log using + * the tag and label that was specified previously, either via + * the constructor or a call to reset(tag, label). If the + * Log.isLoggable is not enabled to at least the Log.VERBOSE + * level for that tag at creation time then the addSplit and + * dumpToLog call will do nothing. + */ + public void reset() { + mDisabled = false; //!Log.isLoggable(mTag, Log.VERBOSE); + if (mDisabled) return; + if (mSplits == null) { + mSplits = new ArrayList(); + mSplitLabels = new ArrayList(); + } else { + mSplits.clear(); + mSplitLabels.clear(); + } + addSplit(null); + } + + /** + * Add a split for the current time, labeled with splitLabel. If + * Log.isLoggable was not enabled to at least the Log.VERBOSE for + * the specified tag at construction or reset() time then this + * call does nothing. + * + * @param splitLabel a label to associate with this split. + */ + public void addSplit(String splitLabel) { + if (mDisabled) return; + long now = SystemClock.elapsedRealtime(); + mSplits.add(now); + mSplitLabels.add(splitLabel); + } + + /** + * Dumps the timings to the log using Log.d(). If Log.isLoggable was + * not enabled to at least the Log.VERBOSE for the specified tag at + * construction or reset() time then this call does nothing. + */ + public void dumpToLog() { + if (mDisabled) return; + Log.d(mTag, mLabel + ": begin"); + final long first = mSplits.get(0); + long now = first; + for (int i = 1; i < mSplits.size(); i++) { + now = mSplits.get(i); + final String splitLabel = mSplitLabels.get(i); + final long prev = mSplits.get(i - 1); + Log.d(mTag, mLabel + ": " + (now - prev) + " ms, " + splitLabel); + } + Log.d(mTag, mLabel + ": end, " + (now - first) + " ms"); + } +}