New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[android] Add Speed class #7955
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I like the approach to measure 👍 A few comments.
if (units == Framework.UNITS_IMPERIAL) | ||
{ | ||
speedValue = MpsToMiph(speedInMetersPerSecond); | ||
unitsString = context.getString(R.string.miles_per_hour); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if these strings will be loaded once (avoid calling context.getString on each call)?
unitsString = context.getString(R.string.kilometers_per_hour); | ||
} | ||
|
||
String formatString = (speedValue < 10.0)? "%.1f" : "%.0f"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this string be pre-cached?
|
||
String formatString = (speedValue < 10.0)? "%.1f" : "%.0f"; | ||
|
||
String speedString = String.format(Locale.getDefault(), formatString, speedValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does caching the locale help to speed up the method?
Are there other alternatives to String.format?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
- Delete the native call for speed formatting.
- Implement decimal separator change detection.
- Update units strings at app startup and when settings are changed.
- 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
This looks nicely done, but I do think it's preferable to keep as much logic as possible in the core, otherwise every platform will end up with its own implementation & it'll be a pain to maintain (you might fancy working on #3676 with your knowledge of the units implementation though!) |
We're always going to have a trade-off between the different approaches. You're right that keeping the implementation in the core will be easier to maintain.
I will take note of this issue/feature request and see if I have time in the future to work on it. In any case, if we want to implement this new feature in the future (i.e. mixing miles with meters), I'd be easier if we have the distance/speed formatting in the core. |
Signed-off-by: Gonzalo Pesquero <gpesquero@yahoo.es>
PR that adds a static Speed class for formatting speed values to strings in Android, instead of using JNI calls.
This is just a draft PR to compare the current c++/JNI string formatting approach vs speed formatting to string in Android, as discussed in #7779 (comment).
This PR runs both speed string formatting implementations (c++/JNI vs Android) in NavMenu.java, logging the time elapsed for each call (measurements have been made on a real Android 9 device via USB debugging):
Android/Java implementation takes 3-4 times longer than the current JNI one, so actually the current implementation seems to be the best approach performance-wise.
The question here is: shall we keep the current approach?, or shall we start to implement speed and distance formatting in Android and remove JNI calls? This second option would also imply to add unit testing for Java/Android.
My opinion: to keep the current approach (string formatting in c++/JNI).
Any feedback in welcome...