Sexy vehicles : map benchmarking

In the beginning of 2016, we decided to start fresh with the way we display markers on Google map. Our solution at the time was capable of handling only a small number of vehicles/stops before causing considerable slowdowns even on high-end devices (50 markers was a limit for LG G4/ Samsung S6). To deal with that problem, we used to hide all markers after a certain zoom level but clearly a better solution was needed.

To start with I created a small benchmark to measure how long it takes to create a marker and place it on the map :

getMapFragment().clear();
LatLng baseCoord = new LatLng (54.68857, 25.28741);
float offset = 0.001f;
Bitmap bitmap = BitmapFactory.decodeResource( getResources(),R.drawable.ic_vehicles_on);
for(int i = 0; i < 30; i++) {
for(int j = 0; j < 30; j++) {
LatLng coord = new LatLng(
baseCoord.latitude + offset * i,
baseCoord.longitude + offset * j);
BitmapDescriptor descriptor =
BitmapDescriptorFactory.fromBitmap(bitmap);
addBenchmarkMarker(descriptor, coord);
}
}
public void addBenchmarkMarker(BitmapDescriptor icon, LatLng latLng){
MarkerOptions markerOptions = new MarkerOptions();
markerOptions
.position(latLng)
.icon(icon);
Marker marker = getMapFragment().addMarker(markerOptions);
}

This code created a 30 x 30 square on the map made of vehicles. I’ve added tracing of BitmapDescriptorFactory.fromBitmap(bitmap) and addBenchmarkMarker(descriptor, coord) by counting a sum of their execution times. Here are the test results on LG G4 :

Average time for creating 900 descriptors : 178.9 ms
Average time for creating 900 markers: 729.7 ms

Clearly those two were areas where some performance improvement could be made. Map marker descriptors could be created once and reused, reducing the descriptor creation time to 0.2 ms. As for the marker, instead of creating it on every update I could just create a marker list once and update marker properties :

int num = 0; 
for(int i = 0; i < 30; i++) {
for (int j = 0; j < 30; j++) {
Marker marker = markerCache.get(num);
marker.setIcon(descriptor2);
marker.setRotation(90);
marker.setPosition(
new LatLng(baseCoord.latitude + offset2 * i,
baseCoord.longitude + offset2 * j));
num++;
}
}

On average, updating took only 145,8 ms, 5 times faster than creating markers from scratch. Encouraged by those results, I went forward to implement my findings in Trafi app. Stay tuned for part 2!