Why are there so many floats in the Android API?
The default floating point type in Java is the double. If you hard code a constant like 2.5
into your program, Java makes it a double automatically. When you do an operation on floats or ints that could potentially benefit from more precision, the type is 'promoted' to a double.
But in the Android API, everything seems to be a float from sound volumes to rectangle coordinates. There's a structure called RectF
used in most drawing; the F is for float. It's really a pain for programmers who are casting promoted doubles back to (float)
pretty often. Don't we all agree that Java code is messy and verbose enough as it is?
Usually math coprocessors and accelerators prefer double in Java because it corresponds to one of the internal types. Is there something about Android's Dalvik VM that prefers floats for some reason? Or are all the floats just a resul开发者_高级运维t of perversion in API design?
On devices without an FPU, the single-precision floating point ops are much faster than the double-precision equivalents. Because of this, the Android framework provides a FloatMath class that replicates some java.lang.Math functions, but with float arguments instead of double.
On recent Android devices with an FPU, the time required for single- and double-precision operations is about the same, and is significantly faster than the software implementation. (The "Designing for Performance" page was written for the G1, and needs to be updated to reflect various changes.)
Incidentally, writing "2.5f" or "(float) 2.5" doesn't matter. Either way, javac knows you want a single-precision float constant, and that's what it generates. You can verify this by writing a sample program and examining the bytecode generated.
Depending on the CPU there will be no Floating Point Unit (FPU). So it has to emulate the FPU in Software. this is faster for a Float than for a Double. Or if the Device has a FPU it will be probably also be faster with Floats.
For metrics that don't need too many significant digits (such as screen offsets), it would be memory-inefficient to use double
s instead of float
s. Maximizing efficiency with regards to memory consumption is vitally important on mobile devices, where pretty much every resource is at a premium. And, when dealing with objects such as Rect
s—that could potentially be allocated by the thousands—it is clearly crucial to cut down on excess bits.
I'm sure there are other reasons too :-)
Weird. Designing for Performance in the guide seems to say "....The common practice on desktop systems is to use floating point freely......so all operations on "float" and "double" are performed in software...." at http://developer.android.com/guide/practices/design/performance.html#avoidfloat
This may make some sense: "....Instructions aren't gratuitously limited to a particular type. For example, instructions that move 32-bit register values without interpretation don't have to specify whether they are moving ints or floats....." at http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html
I think Roman is correct, that the reason is likely mostly intended to reduce memory usage. Consider that when ultimate precision isn't important you will halve the memory needed for numeric variables.
Remember though that it isn't necessary to use casting. Simply append an F to your literal (so 2.5 becomes 2.5f). I don't know if the compiler is smart enough to do the following substitution for you, but if not, this will make your code slightly more efficient as well.
Consider
float x = (float) 2.5;
and
float x = 2.5f;
In the first case, at run time, the program stores a double, then carries out a cast operation, before storing the resulting float value. In the second case the compiler will recognize the value as a float, so at run time you avoid both the storing of a double (however temporarily that might be) and also avoiding the cast operation (since it is already stored as a float).
精彩评论