36

在 Android API 的最新更新中,FloatMath标记有以下 lint-warning:

在旧版本的 Android 中,出于性能考虑,建议在浮点数上使用 android.util.FloatMath。然而,在现代硬件上,double 与 float 一样快(尽管它们占用更多内存),并且在最新版本的 Android 中,由于 JIT 优化 java.lang.Math 的方式,FloatMath 实际上比使用 java.lang.Math 慢. 因此,如果您只针对 Froyo 及更高版本,则应使用 Math 而不是 FloatMath。

这里还提到,double 和 float 在最近的硬件上速度相等。

我在我目前正在处理的应用程序中使用了一些三角数学(针对 Froyo 及更高版本),但不需要高精度,FloatMath所以到目前为止我一直在使用浮点数,并且不需要切换到双精度数。
但是,“use Mathover FloatMath”-recommendation 并没有说明如果 float 是所需的结果,则使用哪一个。

所以,简而言之;哪个更可取?

float foo = FloatMath.sin(bar);

或者

float foo = (float) Math.sin(bar);

顺便说一句,我只有一个 Froyo 设备,所以我不能自己做任何适当的基准测试。

从 API 级别 22 开始,FloatMath 类已被弃用,取而代之的是常规的 Math 类。

4

4 回答 4

15

从下面的结果可以看出,使用 java.lang.Math 处理浮点数比使用双精度数更快,并且比 FloatMath 更快。此外,在 API 级别 17 之前,FloatMath 没有 .exp() 或 .pow()。

在三星 GT_i9295 (4.2.2) 上,2^24 个周期

Math.exp(D)      Total:     7405 ms,     Per Op: 0.0004414 ms
(F)Math.exp(F)   Total:     5153 ms,     Per Op: 0.0003071 ms
FloatMath.exp(F) Total:     8533 ms,     Per Op: 0.0005086 ms

三星上没有 Math.sin 的数据,因为它随机决定忽略 Log.d() >:(

在 HTC Hero_HT99VL (2.3.7) 上,2^12 个周期

Math.sin(D)      Total:       42 ms,     Per Op: 0.0102539 ms
(F)Math.sin(F)   Total:       33 ms,     Per Op: 0.0080566 ms
FloatMath.sin(F) Total:       38 ms,     Per Op: 0.0092773 ms

Math.exp(D)      Total:       56 ms,     Per Op: 0.0136719 ms
(F)Math.exp(F)   Total:       47 ms,     Per Op: 0.0114746 ms

FloatMath.exp()、.pos() 和 .hypot() 需要 API 级别 17

于 2013-09-04T18:06:27.297 回答
5

文档FloatMath说:

数学例程类似于数学中的例程。直接对浮点值执行计算,而不会产生与 double 之间的转换开销。

你的报价说:

在浮点数上操作时,出于性能原因,建议使用 android.util.FloatMath

据推测, 的好处FloatMath总是专门针对您想要 a 时的float,但现在这种好处已被否定。

所以使用:

float foo = (float) Math.sin(bar);

还要考虑到,如果性能如此关键以至于您需要担心这一点,那么也许切换到double毕竟是有道理的(因为不会产生转换成本)。

于 2013-02-28T19:26:11.430 回答
2

我最近只是在研究同样的问题,并发现了这个关于该问题的错误报告。这些Math函数的性能比FloatMath那些函数高出一个数量级,如下面的引用所示:

使用 DDMS,我分析了有问题的代码。下面的每个函数都被调用了 100 倍以上。

       Name                 | Cpu Time / Call
----------------------------------------------
java/lang/Math.sin (D)D     | 0.005
java/lang/Math.cos (D)D     | 0.007
java/lang/Math.sqrt (D)D    | 0.004
android/util/FloatMath.sin  | 0.017
android/util/FloatMath.cos  | 0.017
android/util/FloatMath.sqrt | 0.016

如果您遵循AOSP 树中的文档更改,您会在此处看到Math函数优先于FloatMath具有 JIT 的 android 版本,这基本上是 Froyo (2.2) 及更高版本的任何内容。

于 2013-03-15T17:12:35.370 回答
-1

如果性能如此重要,那么您可能不想在double每次计算某些东西时浪费时间与 s 进行转换。

据我了解,在较旧的硬件上,浮点数比双精度更快,因此您需要一个用于浮点数的数学库。现在,“在现代硬件上,双精度与浮点数一样快”,因此您应该使用Math带双精度的默认值。

如果值是浮点数对您的应用程序很重要(例如,因为内存消耗),您应该继续使用 FloatMath,因为float foo = (float) Math.sin(bar);如果您经常使用它会变得烦人。

于 2013-02-28T19:40:56.580 回答