Open Codain opened 3 years ago
Not clear if this can improve any situation with CPU/battery, so it's probably a tiny-tiny peak of the iceberg
I think this is valuable research and worth pursuing.
But I also think this does not address the original issue: It is quite unclear why some devices last for days and others only for hours. Quite possibly graphics is part of the problem, like animation for panning or compass rotation, which may be handled differently on different hardwares?
🚀 feature request
Description
Following discussion in issue #9928 I used my OsmAnd non-developper eyes to try to catch straightforward optimizations.
Disclaimer: I don't have the ability to run those modifications and to perform some performance analysis. Some of them may be false optimization (I'm not aware of how Java might or might not optimize things by itself). But taking into account my experience they usually are interesting to consider. I share my thought with the good intention to try to make OsmAnd even better. Also a static analysis tool would probably help to enhance my sampling. I can propose some pull requests covering those items but with no ability to validate them.
Background: I'm an embedded software developper having developped several graphical engines and map rendering from databases on small sized targets in C/C++. Consequently I faced a number of challenges to reduce as much as possible CPU consumption and latency perceived by user, some of those challenges close to OsmAnd challenges. I'm also an OsmAnd+ with Live feature user willing to save my battery.
I focused on "easy" changes that don't break overall software architecture (except probably 13).
Describe the solution you'd like
/ 180 * Math.PI
,* Math.PI / 180
,/ Math.PI * 180
,* 180 / Math.PI
and also some use oftoRadians(x)
orMath.toRadians(x)
(and probablytoDegrees(x)
?). I suggest to harmonize and to do a benchmark between a multiplication with a constant (* SomeClass.TO_RADIANS
) or a function call (toRadians(x)
). I have the feeling that replacing a function call by a multiplication is better but might be wrong due to Java bad knowledge. By the way I would use 180.0 since Pi is already a float and to have an explicit accuracy.2.0 * Math.PI
(such as in https://github.com/osmandapp/OsmAnd/blob/0cdbff3454cb3351a603d3e4120f8d661c1a749c/OsmAnd-java/src/main/java/net/osmand/util/SunriseSunset.java#L385), replace by constants likeMoreMath.TWO_PI
(orMoreMath.TWO_PI_D
).Math.PI / 2
(MoreMath.HALF_PI
) orMath.PI / 15
(constant to be created?)./ Math.PI
by multiplication with a constant equaling one over Pi.Math.sqrt(2)
and others constant square roots by a constant (such as in https://github.com/osmandapp/OsmAnd/blob/0cdbff3454cb3351a603d3e4120f8d661c1a749c/OsmAnd/src/net/osmand/plus/views/DirectionDrawable.java#L146)Math.cos(lat1)
is computed 3 times andMath.cos(lat2)
2 times insqrt(a) < sqrt(b)
will give same result thana < b
with a and b positive, which is always the case when we have a sum of squares. When using a distance function I suggest to rename it to make it clear it returned a squared distance (i.e.getDistanceBetweenColors
becominggetSquaredDistanceBetweenColors
). In all cases do not compute the square root, compare squared distances and make sure variables reflects they are square distances and not distances.MapUtils.getTileNumberX(something, MapUtils.get31LongitudeX(o.getPoint31XTile(i)))
(such as in https://github.com/osmandapp/OsmAnd/blob/0cdbff3454cb3351a603d3e4120f8d661c1a749c/OsmAnd-java/src/main/java/net/osmand/binary/BinaryMapIndexFilter.java#L63) when computing distances or areas, always for X and Y. I wonder if there would be something to do here (precompute and/or get X and Y simultaneously).getLabelY
angle
andangleRad
after if statement withcontinue
.px
,py
,x
,y
andangle
getPixXFromLatLon
is nearly always used withgetPixYFromLatLon
but both of them callMapUtils.getTileNumberX
andMapUtils.getTileNumberY
. There would probably be a benefit to replace by agetPixXYFromLatLon
callsin
,cos
andlog
calls (which would respectively gives-3.05915251782887
and+3.05915251782887
).Math.sin(E2)
is called 4 times, replace by one call.Math.sin(dLat / 2)
is called two times andMath.sin(dLon / 2)
two timesFeel free to comment 👍 👎 .