-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize Memory Usage by Interning Frequently Occurring Strings in JS…
…ON (#1585) * Intern IntersectionLanes's indication strings to save memory. * Optimize StepManeuver json parsing
- Loading branch information
1 parent
be2ba14
commit 05a7bfe
Showing
7 changed files
with
294 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
...odels/src/main/java/com/mapbox/api/directions/v5/models/IntersectionLanesTypeAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package com.mapbox.api.directions.v5.models; | ||
|
||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParser; | ||
import com.google.gson.TypeAdapter; | ||
import com.google.gson.stream.JsonReader; | ||
import com.google.gson.stream.JsonToken; | ||
import com.google.gson.stream.JsonWriter; | ||
import com.mapbox.api.directions.v5.utils.ParseUtils; | ||
|
||
import java.io.IOException; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* A TypeAdapter for {@link IntersectionLanes} used to optimize JSON deserialization. | ||
* | ||
* <p>Strings in {@link IntersectionLanes#indications()} and | ||
* {@link IntersectionLanes#validIndication()} can accept a limited set of possible values | ||
* (e.g., "straight," "right," "left," etc.). | ||
* This adapter invokes {@link String#intern()} on these strings to save memory.</p> | ||
*/ | ||
class IntersectionLanesTypeAdapter extends TypeAdapter<IntersectionLanes> { | ||
|
||
private final TypeAdapter<IntersectionLanes> defaultAdapter; | ||
|
||
IntersectionLanesTypeAdapter(TypeAdapter<IntersectionLanes> defaultAdapter) { | ||
this.defaultAdapter = defaultAdapter; | ||
} | ||
|
||
@Override | ||
public void write(JsonWriter out, IntersectionLanes value) throws IOException { | ||
defaultAdapter.write(out, value); | ||
} | ||
|
||
@Override | ||
public IntersectionLanes read(JsonReader in) throws IOException { | ||
if (in.peek() == JsonToken.NULL) { | ||
in.nextNull(); | ||
return null; | ||
} | ||
|
||
final JsonObject jsonObject = JsonParser.parseReader(in).getAsJsonObject(); | ||
|
||
final IntersectionLanes.Builder builder = IntersectionLanes.builder(); | ||
Map<String, JsonElement> unrecognized = null; | ||
|
||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { | ||
final String key = entry.getKey(); | ||
final JsonElement value = entry.getValue(); | ||
|
||
if (value.isJsonNull()) { | ||
continue; | ||
} | ||
|
||
switch (key) { | ||
case "valid": | ||
builder.valid(value.getAsBoolean()); | ||
break; | ||
|
||
case "active": | ||
builder.active(value.getAsBoolean()); | ||
break; | ||
|
||
case "valid_indication": | ||
builder.validIndication(value.getAsString().intern()); | ||
break; | ||
|
||
case "indications": | ||
builder.indications(ParseUtils.parseAndInternJsonStringArray(value.getAsJsonArray())); | ||
break; | ||
|
||
case "payment_methods": | ||
builder.paymentMethods(ParseUtils.parseAndInternJsonStringArray(value.getAsJsonArray())); | ||
break; | ||
|
||
default: | ||
if (unrecognized == null) { | ||
unrecognized = new LinkedHashMap<>(); | ||
} | ||
unrecognized.put(key, value); | ||
break; | ||
} | ||
} | ||
|
||
return builder | ||
.unrecognizedJsonProperties(unrecognized) | ||
.build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
...ons-models/src/main/java/com/mapbox/api/directions/v5/models/StepManeuverTypeAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package com.mapbox.api.directions.v5.models; | ||
|
||
import com.google.gson.JsonArray; | ||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParser; | ||
import com.google.gson.TypeAdapter; | ||
import com.google.gson.stream.JsonReader; | ||
import com.google.gson.stream.JsonToken; | ||
import com.google.gson.stream.JsonWriter; | ||
|
||
import java.io.IOException; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* A TypeAdapter for {@link StepManeuver} used to optimize JSON deserialization. | ||
* | ||
* <p>Strings {@link StepManeuver#type()} and {@link StepManeuver#modifier()} can accept | ||
* a limited set of possible values. | ||
* This adapter invokes {@link String#intern()} on these strings to save memory.</p> | ||
*/ | ||
class StepManeuverTypeAdapter extends TypeAdapter<StepManeuver> { | ||
private final TypeAdapter<StepManeuver> defaultAdapter; | ||
|
||
StepManeuverTypeAdapter(TypeAdapter<StepManeuver> defaultAdapter) { | ||
this.defaultAdapter = defaultAdapter; | ||
} | ||
|
||
@Override | ||
public void write(JsonWriter out, StepManeuver value) throws IOException { | ||
defaultAdapter.write(out, value); | ||
} | ||
|
||
@Override | ||
public StepManeuver read(JsonReader in) throws IOException { | ||
if (in.peek() == JsonToken.NULL) { | ||
in.nextNull(); | ||
return null; | ||
} | ||
|
||
final JsonObject jsonObject = JsonParser.parseReader(in).getAsJsonObject(); | ||
|
||
final StepManeuver.Builder builder = StepManeuver.builder(); | ||
Map<String, JsonElement> unrecognized = null; | ||
|
||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { | ||
final String key = entry.getKey(); | ||
final JsonElement value = entry.getValue(); | ||
|
||
if (value.isJsonNull()) { | ||
continue; | ||
} | ||
|
||
switch (key) { | ||
case "location": | ||
final JsonArray jsonArray = value.getAsJsonArray(); | ||
final double[] locations = new double[jsonArray.size()]; | ||
for (int i = 0; i < jsonArray.size(); ++i) { | ||
locations[i] = jsonArray.get(i).getAsDouble(); | ||
} | ||
builder.rawLocation(locations); | ||
break; | ||
|
||
case "bearing_before": | ||
builder.bearingBefore(value.getAsDouble()); | ||
break; | ||
|
||
case "bearing_after": | ||
builder.bearingAfter(value.getAsDouble()); | ||
break; | ||
|
||
case "instruction": | ||
builder.instruction(value.getAsString()); | ||
break; | ||
|
||
case "type": | ||
builder.type(value.getAsString().intern()); | ||
break; | ||
|
||
case "modifier": | ||
builder.modifier(value.getAsString().intern()); | ||
break; | ||
|
||
case "exit": | ||
builder.exit(value.getAsInt()); | ||
break; | ||
|
||
default: | ||
if (unrecognized == null) { | ||
unrecognized = new LinkedHashMap<>(); | ||
} | ||
unrecognized.put(key, value); | ||
break; | ||
} | ||
} | ||
|
||
return builder | ||
.unrecognizedJsonProperties(unrecognized) | ||
.build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters