WIP: [android] Add Speed class #7955
|
@ -1953,4 +1953,10 @@ Java_app_organicmaps_Framework_nativeGetKayakHotelLink(JNIEnv * env, jclass, jst
|
|||
return url.empty() ? nullptr : jni::ToJavaString(env, url);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_app_organicmaps_Framework_nativeGetUnits(JNIEnv *, jclass)
|
||||
{
|
||||
return static_cast<jint>(measurement_utils::GetMeasurementUnits());
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -57,6 +57,14 @@ JNIEXPORT jobject JNICALL Java_app_organicmaps_util_StringUtils_nativeFormatSpee
|
|||
platform::GetLocalizedSpeedUnits(units));
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_app_organicmaps_util_StringUtils_nativeStringFormatSpeedAndUnits(
|
||||
JNIEnv * env, jclass thiz, jdouble metersPerSecond)
|
||||
{
|
||||
auto const units = measurement_utils::GetMeasurementUnits();
|
||||
return jni::ToJavaString(env, measurement_utils::FormatSpeedNumeric(metersPerSecond, units) +
|
||||
";" + platform::GetLocalizedSpeedUnits(units));
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_app_organicmaps_util_StringUtils_nativeFormatDistance(JNIEnv * env, jclass, jdouble distanceInMeters)
|
||||
{
|
||||
|
|
|
@ -60,6 +60,10 @@ public class Framework
|
|||
public static final int ROUTER_TYPE_TRANSIT = 3;
|
||||
public static final int ROUTER_TYPE_RULER = 4;
|
||||
|
||||
// Units values shall be the same as the ones defined in c++ in <platform/measurement_utils.hpp>.
|
||||
public static final int UNITS_METRIC = 0;
|
||||
public static final int UNITS_IMPERIAL = 1;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({ROUTE_REBUILD_AFTER_POINTS_LOADING})
|
||||
public @interface RouteRecommendationType {}
|
||||
|
@ -460,4 +464,6 @@ public class Framework
|
|||
@Nullable
|
||||
public static native String nativeGetKayakHotelLink(@NonNull String countryIsoCode, @NonNull String uri,
|
||||
long firstDaySec, long lastDaySec, boolean isReferral);
|
||||
|
||||
public static native int nativeGetUnits();
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ public class NavigationController implements TrafficManager.TrafficCallback,
|
|||
updateVehicle(info);
|
||||
|
||||
updateStreetView(info);
|
||||
mNavMenu.update(info);
|
||||
mNavMenu.update(info, Framework.nativeGetUnits());
|
||||
}
|
||||
|
||||
private void updateStreetView(@NonNull RoutingInfo info)
|
||||
|
|
171
android/app/src/main/java/app/organicmaps/util/Speed.java
Normal file
|
@ -0,0 +1,171 @@
|
|||
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
package app.organicmaps.util;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import android.content.Context;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import android.util.Pair;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import java.text.DecimalFormat;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import java.text.DecimalFormatSymbols;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import java.text.NumberFormat;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import java.util.Formatter;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import java.util.Locale;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import app.organicmaps.Framework;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
import app.organicmaps.util.log.Logger;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
public class Speed
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private static String mUnitStringKmh = "km/h";
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private static String mUnitStringMiph = "mph";
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private static char mDecimalSeparator = Character.MIN_VALUE;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
public static double MpsToKmph(double mps) { return mps * 3.6; }
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
public static double MpsToMiph(double mps) { return mps * 2.236936; }
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
public static void setUnitStringKmh(String unitStringKmh) { mUnitStringKmh = unitStringKmh; }
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
public static void setUnitStringMiph(String unitStringMiph) { mUnitStringMiph = unitStringMiph; }
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private final static DecimalFormat mDecimalFormatNoDecimal = new DecimalFormat("#");
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private final static DecimalFormat mDecimalFormatOneDecimal = new DecimalFormat("0.0");
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private final static Locale mLocale = Locale.getDefault();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private final static StringBuilder mSb = new StringBuilder();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private final static Formatter mFormatter = new Formatter(mSb, mLocale);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private final static NumberFormat mNumberFormatNoDecimal = NumberFormat.getInstance(mLocale);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
private final static NumberFormat mNumberFormatOneDecimal = NumberFormat.getInstance(mLocale);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
public static Pair<String, String> formatMeasurements(double speedInMetersPerSecond, int units,
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Context context)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
double speedValue;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
String unitsString;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (units == Framework.UNITS_IMPERIAL)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedValue = MpsToMiph(speedInMetersPerSecond);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
unitsString = mUnitStringMiph;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
else
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedValue = MpsToKmph(speedInMetersPerSecond);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
unitsString = mUnitStringKmh;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
// Option 1: String.format()
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long start1 = System.nanoTime();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
String formatString = (speedValue < 10.0)? "%.1f" : "%.0f";
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
![]() Can this string be pre-cached? Can this string be pre-cached?
|
||||
String speedString = String.format(mLocale, formatString, speedValue);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long elapsed1 = System.nanoTime() - start1;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Logger.i("LOCALE_MEASURE", "1) " + speedString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
// Option 2: DecimalFormat class
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long start2 = System.nanoTime();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (speedValue < 10.0)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = mDecimalFormatOneDecimal.format(speedValue);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
else
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = mDecimalFormatNoDecimal.format(speedValue);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long elapsed2 = System.nanoTime() - start2;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Logger.i("LOCALE_MEASURE", "2) " + speedString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
// Option 3: Long.toString() + StringBuffer.insert()
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long start3 = System.nanoTime();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (speedValue < 10.0)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = Long.toString(Math.round(speedValue * 10.0));
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
StringBuffer buffer = new StringBuffer(speedString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (mDecimalSeparator == Character.MIN_VALUE)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
mDecimalSeparator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
// For low values (< 1.0), force to have 2 characters in string.
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (buffer.length() < 2)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
buffer.insert(0, "0");
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
buffer.insert(1, mDecimalSeparator);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = buffer.toString();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
else
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = Long.toString(Math.round(speedValue));
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long elapsed3 = System.nanoTime() - start3;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Logger.i("LOCALE_MEASURE", "3) " + speedString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
// Option 4: Formatter class
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
mSb.setLength(0);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long start4 = System.nanoTime();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (speedValue < 10.0)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
mFormatter.format("%.1f", speedValue);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
else
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
mFormatter.format("%d", Math.round(speedValue));
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = mSb.toString();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long elapsed4 = System.nanoTime() - start4;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Logger.i("LOCALE_MEASURE", "4) " + speedString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
// Option 5: NumberFormat class
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
mNumberFormatNoDecimal.setMaximumFractionDigits(0);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
mNumberFormatOneDecimal.setMaximumFractionDigits(1);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long start5 = System.nanoTime();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (speedValue < 10.0)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = mNumberFormatOneDecimal.format(speedValue);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
else
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = mNumberFormatNoDecimal.format(Math.round(speedValue));
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
long elapsed5 = System.nanoTime() - start5;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Logger.i("LOCALE_MEASURE", "5) " + speedString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
String text = String.format(Locale.US,
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
"Java calls: %5d / %5d / %5d / %5d / %5d",
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Math.round(0.001 * elapsed1),
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Math.round(0.001 * elapsed2),
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Math.round(0.001 * elapsed3),
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Math.round(0.001 * elapsed4),
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Math.round(0.001 * elapsed5));
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Logger.i("LOCALE_MEASURE", text);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
return new Pair<>(speedString, unitsString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
public static Pair<String, String> format(double speedInMetersPerSecond, int units,
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
Context context)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
double speedValue;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
String unitsString;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (units == Framework.UNITS_IMPERIAL)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedValue = MpsToMiph(speedInMetersPerSecond);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
unitsString = mUnitStringMiph;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
else
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedValue = MpsToKmph(speedInMetersPerSecond);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
unitsString = mUnitStringKmh;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
String speedString;
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (speedValue < 10.0)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
{
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = Long.toString(Math.round(speedValue * 10.0));
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
StringBuffer buffer = new StringBuffer(speedString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (mDecimalSeparator == Character.MIN_VALUE)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
mDecimalSeparator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
// For low values (< 1.0), force to have 2 characters in string.
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
if (buffer.length() < 2)
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
buffer.insert(0, "0");
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
buffer.insert(1, mDecimalSeparator);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = buffer.toString();
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
else
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
speedString = Long.toString(Math.round(speedValue));
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
return new Pair<>(speedString, unitsString);
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
||||
}
|
||||
![]() What if these strings will be loaded once (avoid calling context.getString on each call)? What if these strings will be loaded once (avoid calling context.getString on each call)?
![]() Does caching the locale help to speed up the method? Are there other alternatives to String.format? Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
gpesquero
commented
I've made some timing comparison with 2 other alternatives to You can find the code for this comparison in the function
These are the average times for each option:
Option 3 is by far the fastest one, though it requires to insert manually the decimal separator into the string (as we are doing in c++ right now). With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there. > Are there other alternatives to String.format?
I've made some timing comparison with 2 other alternatives to `String.format()`.
You can find the code for this comparison in the function `formatMeasurements()`.
- Option 1: `String.format(Locale, double)`
- Option 2: `DecimalFormat("#.#").format(double)`
- Option 3: `Long.toString(Math.round(speedValue * 10.0))` + `StringBuffer(String).insert(1, char)` (inserting the decimal separator into the string)
These are the average times for each option:
- Option 1: 250 us
- Option 2: 55 us
- Option 3: 15 us
Option 3 is _by far_ the fastest one, though it requires to insert _manually_ the decimal separator into the string (as we are doing in c++ right now).
With option 3, we even get a better performance compared to the current JNI calls. These are the new measurements:
```
Current / New / Diff (x1.1f)
210 / 27 / -184 (x0.1)
123 / 45 / -78 (x0.4)
111 / 20 / -90 (x0.2)
112 / 21 / -91 (x0.2)
115 / 18 / -97 (x0.2)
112 / 25 / -87 (x0.2)
132 / 22 / -110 (x0.2)
126 / 23 / -103 (x0.2)
123 / 29 / -94 (x0.2)
120 / 22 / -97 (x0.2)
185 / 28 / -156 (x0.2)
140 / 44 / -97 (x0.3)
123 / 22 / -101 (x0.2)
130 / 26 / -104 (x0.2)
111 / 22 / -89 (x0.2)
108 / 16 / -92 (x0.1)
123 / 20 / -103 (x0.2)
120 / 29 / -91 (x0.2)
127 / 21 / -106 (x0.2)
```
This 3rd option seems to be a good solution performance-wise, so we could start to implement it in this PR, including:
1. Delete the native call for speed formatting.
2. Implement decimal separator change detection.
3. Update units strings at app startup and when settings are changed.
4. Implement speed formatting unit tests in Android
I have to check also if Android Auto also uses native calls for speed formatting, and see if this solution also applies there.
![]() What about separating thousands? There are also Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android. As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized? What about separating thousands? There are also `Formatter formatter = new Formatter(sb, Locale.US);` and `java.text.NumberFormat`
Note that there are also values displayed in the Place Page (altitude, speed) that also should be formatted. Ideally, doing it in one place and supporting only one implementation would be the best way to go than supporting C++ version and custom Java formatters for Android.
As you've already established a test environment, does it make sense to check how the current C++ implementation can be sped up? Is there any overhead there? Can JNI calls be optimized?
gpesquero
commented
Hello again @biodranik !! I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
And here is a sample of time values measured while running on an actual Android device:
The fastest implementation is always Option 3: using Long.toString() and inserting the decimal separator "manually". Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator). Hello again @biodranik !!
I've made a few more tests / benchmarks for the speed format in Java, using different implementations:
* Option 1: String.format()
* Option 2: DecimalFormat class
* Option 3: Long.toString() + StringBuffer.insert()
* Option 4: Formatter class
* Option 5: NumberFormat class
And here is a sample of time values measured while running on an actual Android device:
```
Opt1 / Opt2 / Opt3 / Opt4 / Opt5 (values in us)
439 / 99 / 29 / 299 / 61
391 / 72 / 25 / 266 / 60
403 / 101 / 22 / 311 / 93
476 / 104 / 45 / 649 / 229
387 / 75 / 20 / 254 / 60
821 / 82 / 25 / 305 / 76
434 / 73 / 20 / 231 / 58
480 / 76 / 20 / 275 / 65
435 / 97 / 31 / 404 / 161
377 / 77 / 20 / 300 / 69
595 / 119 / 23 / 354 / 74
399 / 130 / 35 / 467 / 121
310 / 66 / 19 / 333 / 73
344 / 68 / 18 / 390 / 88
504 / 230 / 38 / 476 / 62
```
The fastest implementation is *always* Option 3: using Long.toString() and inserting the decimal separator "manually".
This "manual" approach is more or less the same as the one that we have running in c++ in function ToStringPrecisionLocale().
Note that we're dealing here with speed formatting, so only decimal separator is formatted (No thousands separator).
gpesquero
commented
For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
This new second implementation is usually faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
Is it worth the implementation of this second approach? It's debatable... Any feedback is welcomed!! For the benchmarking of the current c++ implementation, I've implemented an additional JNI call for speed formatting that, instead of returning a Pair<String, String> class, returns a single String class with both the value and unit separated by a semicolon ";".
* Option 1 (current): native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
* Option 2 (new): native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
* Option 3: Java formatting implementation (Option 3 in previous benchmarking)
This new second implementation is _usually_ faster that the current one (but always slower than the 3rd implementation: fast Java manual approach):
1= 166 / 2= 144 / 3= 37
1= 159 / 2= 412 / 3= 70
1= 159 / 2= 147 / 3= 36
1= 181 / 2= 159 / 3= 42
1= 157 / 2= 145 / 3= 39
1= 430 / 2= 669 / 3= 58
1= 141 / 2= 118 / 3= 32
1= 537 / 2= 149 / 3= 39
1= 155 / 2= 119 / 3= 32
1= 223 / 2= 137 / 3= 35
1= 142 / 2= 108 / 3= 30
1= 169 / 2= 125 / 3= 33
1= 145 / 2= 139 / 3= 37
Is it worth the implementation of this second approach? It's debatable...
Any feedback is welcomed!!
![]() Thanks! Very interesting measurements. Let's check if we can make C++ code faster first ) Thanks! Very interesting measurements. Let's check if we can make C++ code faster first )
|
|
@ -30,6 +30,7 @@ public class StringUtils
|
|||
public static native String[] nativeFilterContainsNormalized(String[] strings, String substr);
|
||||
|
||||
public static native Pair<String, String> nativeFormatSpeedAndUnits(double metersPerSecond);
|
||||
public static native String nativeStringFormatSpeedAndUnits(double metersPerSecond);
|
||||
public static native Distance nativeFormatDistance(double meters);
|
||||
@NonNull
|
||||
public static native Pair<String, String> nativeGetLocalizedDistanceUnits();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package app.organicmaps.widget.menu;
|
||||
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
@ -15,12 +16,16 @@ import app.organicmaps.location.LocationHelper;
|
|||
import app.organicmaps.routing.RoutingInfo;
|
||||
import app.organicmaps.sound.TtsPlayer;
|
||||
import app.organicmaps.util.Graphics;
|
||||
import app.organicmaps.util.Speed;
|
||||
import app.organicmaps.util.StringUtils;
|
||||
import app.organicmaps.util.UiUtils;
|
||||
import app.organicmaps.util.log.Logger;
|
||||
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class NavMenu
|
||||
|
@ -203,22 +208,57 @@ public class NavMenu
|
|||
mTimeEstimate.setText(localTime.format(DateTimeFormatter.ofPattern(format)));
|
||||
}
|
||||
|
||||
private void updateSpeedView(@NonNull RoutingInfo info)
|
||||
private void updateSpeedView(@NonNull RoutingInfo info, int units)
|
||||
{
|
||||
final Location last = LocationHelper.from(mActivity).getSavedLocation();
|
||||
if (last == null)
|
||||
return;
|
||||
|
||||
// Log measurements for different Java implementations.
|
||||
Speed.formatMeasurements(last.getSpeed(), units, mActivity.getApplicationContext());
|
||||
|
||||
// Speed formatting using native calls.
|
||||
long start1 = System.nanoTime();
|
||||
Pair<String, String> speedAndUnits = StringUtils.nativeFormatSpeedAndUnits(last.getSpeed());
|
||||
long elapsed1 = System.nanoTime() - start1;
|
||||
|
||||
mSpeedUnits.setText(speedAndUnits.second);
|
||||
mSpeedValue.setText(speedAndUnits.first);
|
||||
|
||||
// Speed formatting using native calls. Speed and units is returned in a single string.
|
||||
long start2 = System.nanoTime();
|
||||
String speedAndUnitsString = StringUtils.nativeStringFormatSpeedAndUnits(last.getSpeed());
|
||||
// Speed and units are separated by semicolon ";" in returned string.
|
||||
int separatorPos = speedAndUnitsString.indexOf(";");
|
||||
String speedString = speedAndUnitsString.substring(0, separatorPos);
|
||||
String unitsString = speedAndUnitsString.substring(separatorPos + 1);
|
||||
long elapsed2 = System.nanoTime() - start2;
|
||||
|
||||
mSpeedUnits.setText(speedString);
|
||||
mSpeedValue.setText(unitsString);
|
||||
|
||||
// Speed formatting using Android Java calls.
|
||||
long start3 = System.nanoTime();
|
||||
speedAndUnits = Speed.format(last.getSpeed(), units, mActivity.getApplicationContext());
|
||||
long elapsed3 = System.nanoTime() - start3;
|
||||
|
||||
mSpeedUnits.setText(speedAndUnits.second);
|
||||
mSpeedValue.setText(speedAndUnits.first);
|
||||
|
||||
String text = String.format(Locale.US,
|
||||
"Native calls: %5d / %5d / %5d",
|
||||
Math.round(0.001 * elapsed1),
|
||||
Math.round(0.001 * elapsed2),
|
||||
Math.round(0.001 * elapsed3));
|
||||
|
||||
Logger.i("LOCALE_MEASURE", text);
|
||||
|
||||
mSpeedViewContainer.setActivated(info.isSpeedLimitExceeded());
|
||||
}
|
||||
|
||||
public void update(@NonNull RoutingInfo info)
|
||||
public void update(@NonNull RoutingInfo info, int units)
|
||||
{
|
||||
updateSpeedView(info);
|
||||
updateSpeedView(info, units);
|
||||
updateTime(info.totalTimeInSeconds);
|
||||
mDistanceValue.setText(info.distToTarget.mDistanceStr);
|
||||
mDistanceUnits.setText(info.distToTarget.getUnitsStr(mActivity.getApplicationContext()));
|
||||
|
|
What if these strings will be loaded once (avoid calling context.getString on each call)?
Does caching the locale help to speed up the method?
Are there other alternatives to String.format?