Ответ 1
В зависимости от ЦП не будет модуля с плавающей точкой (FPU). Поэтому он должен эмулировать FPU в программном обеспечении. это быстрее для Float, чем для Double. Или, если у устройства есть FPU, он, вероятно, также будет быстрее с Floats.
Тип с плавающей запятой по умолчанию в Java - это double. Если вы произвольно скопируете константу типа 2.5
в свою программу, Java автоматически сделает ее двойной. Когда вы выполняете операцию над поплавками или ints, которые потенциально могут извлечь выгоду из большей точности, тип "повышается" до double.
Но в Android API все кажется плавающим из томов звука в прямоугольные координаты. В большинстве рисунков используется структура, называемая RectF
; F - для поплавка. Это действительно боль для программистов, которые бросают продвинутые двойники обратно на (float)
довольно часто. Разве мы не все согласны с тем, что Java-код довольно грязный и достаточно подробный, как есть?
Обычно математические сопроцессоры и ускорители предпочитают двойную работу на Java, потому что она соответствует одному из внутренних типов. Есть ли что-то в Android Dalvik VM, которое почему-то предпочитает поплавки? Или все поплавки являются результатом искажений в дизайне API?
В зависимости от ЦП не будет модуля с плавающей точкой (FPU). Поэтому он должен эмулировать FPU в программном обеспечении. это быстрее для Float, чем для Double. Или, если у устройства есть FPU, он, вероятно, также будет быстрее с Floats.
На устройствах без FPU операторы с плавающей запятой с одинарной точностью намного быстрее, чем эквиваленты с двойной точностью. Из-за этого инфраструктура Android предоставляет класс FloatMath, который реплицирует некоторые функции java.lang.Math, но с аргументами float вместо double.
На последних устройствах Android с FPU время, требуемое для операций с одиночной и двойной точностью, примерно одинаковое и значительно быстрее, чем реализация программного обеспечения. (Страница "Проектирование для производительности" была написана для G1, и ее необходимо обновить, чтобы отразить различные изменения.)
Кстати, запись "2.5f" или "(float) 2.5" не имеет значения. В любом случае, javac знает, что вам нужна константа float с одной точностью и то, что она генерирует. Вы можете проверить это, написав пример программы и проанализировав байткод.
Для показателей, которым не нужно слишком много значимых цифр (например, смещения экрана), было бы неэффективно использовать double
вместо float
s. Максимизация эффективности в отношении потребления памяти жизненно важна на мобильных устройствах, где почти каждый ресурс стоит на высоком уровне. И при работе с объектами, такими как Rect
s &mdash, которые потенциально могут быть выделены тысячами, очевидно, важно сократить лишние биты.
Я уверен, что есть и другие причины: -)
Weird. Проектирование производительности в руководстве, по-видимому, говорит: "... Обычная практика для настольных систем - свободно использовать плавающие точки... поэтому все операции с" плавающей "и" двойной "выполняются в программном обеспечении.... http://developer.android.com/guide/practices/design/performance.html#avoidfloat
Это может иметь смысл: "... Инструкции не могут быть ограничены конкретным типом. Например, инструкции, которые перемещают 32-битные значения регистра без интерпретации, не должны указывать, перемещают ли они ints или плавают....." на http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html
Я думаю, что Роман прав, что причина, скорее всего, в основном предназначена для сокращения использования памяти. Считайте, что, когда предельная точность не важна, вы уменьшите вдвое память, необходимую для числовых переменных.
Помните, что нет необходимости использовать кастинг. Просто добавьте F в свой литерал (так 2.5 станет 2.5f). Я не знаю, достаточно ли укомплектован компилятор для выполнения следующей подстановки для вас, но если нет, это также сделает ваш код более эффективным.
Рассмотрим
float x = (float) 2.5;
и
float x = 2.5f;
В первом случае во время выполнения программа сохраняет двойной, а затем выполняет операцию литья, прежде чем сохранять полученное значение float. Во втором случае компилятор распознает значение как float, поэтому во время выполнения вы избегаете как сохранения двойника (хотя бы временно это может быть), так и избегания операции литья (поскольку она уже хранится как float).