浮动还是双重?

时间:2011-06-03 20:41:34

标签: android performance memory floating-point

当执行arithimic(+ - * /%)时,哪个是更快,双倍或浮动,为了内存原因,是否值得使用float?精确度不是一个问题。

即使想到这一点,也请随意叫我疯了。只是好奇,因为我看到我正在使用的花车数量越来越大。

编辑1: 这是android的唯一原因是因为这是我认为记忆很重要的地方;我甚至不会问这个用于桌面开发。

8 个答案:

答案 0 :(得分:25)

现在两种类型的处理速度在CPU中大致相同
“使用任何精度来获得可接受的结果。”

相关问题已在SO here is one上多次询问。

修改:

  

在速度方面,更现代的硬件上浮动和双重没有区别。

请从developer.android.com查看此article

答案 1 :(得分:15)

ADT v21 lint消息建议使用Double而不是Float,因为来自Froyo的Dalvik中的JIT(及时)优化(API 8及更高版本)。

我正在使用FloatMath.sin,它在“解释问题”上下文菜单下使用以下内容建议使用Math.sin。它读给我的是一个与double vs float相关的一般信息,而不仅仅是与trig相关的信息。

“在旧版本的Android中,使用  推荐使用android.util.FloatMath  在浮子上操作时的性能原因。  然而,在现代硬件上,双打同样快  作为浮动(虽然他们需要更多的记忆),并在  最近的Android版本,实际上就是FloatMath  由于JIT的方式,比使用java.lang.Math慢  优化java.lang.Math。因此,你应该使用  如果您只是定位,则数学而不是FloatMath  Froyo及以上。“

希望这有帮助。

答案 2 :(得分:6)

我不建议快速操作,但我相信对浮点数的操作会更快,因为它们是32位而不是64位双打。

答案 3 :(得分:6)

http://developer.android.com/training/articles/perf-tips.html#AvoidFloat

  

避免使用浮点

     

根据经验,浮点比整数慢约2倍   Android设备。

     

速度方面,浮动和双重之间没有区别   更现代的硬件。在空间方面,双倍大2倍。与桌面一样   机器,假设空间不是问题,你应该更喜欢双倍   浮。

     

此外,即使对于整数,某些处理器也会硬件增加   缺乏硬件鸿沟。在这种情况下,整数除法和模数   操作是在软件中执行的 - 可以考虑是否   你正在设计一个哈希表或做很多数学。

答案 4 :(得分:4)

浮点数是32位或4字节

double是64位或8字节

所以是的,根据sun java认证书,花车的大小只有一半。

答案 5 :(得分:3)

  

在速度方面,在更现代的硬件上,float和double之间没有区别。

非常便宜的设备似乎有一个有限的FPU,浮动速度比双倍快。我在CMX设备上进行了测试,该设备目前是世界上最便宜的平板电脑之一:

  • “float”测试代码需要4.7秒
  • 与“double”相同的代码需要6.6秒
  

这个问题曾被问过几次......

是。因为不同类型的硬件的答案不同。在台式计算机上,double与float具有相同的速度。在没有FPU的设备上(对于WLAN路由器黑客来说很有趣)浮动比双倍快2到5倍;在具有32位FPU(通常在工业和汽车应用中常见)的设备上甚至可达100次。

  

请查看这篇文章......

文章的最后一部分说明您必须对要使用的硬件设备进行时间测量才能100%确定。

答案 6 :(得分:1)

引用的android文档表明整数更适合快速操作。这看起来有点奇怪但是使用整数和浮点数与双打的算法的速度取决于几个层次:

  1. JIT或VM:这些会将数学运算转换为主机的本机指令集,并且该转换会对性能产生很大影响。由于底层硬件可能因平台而异,因此编写在所有情况下都会发出最佳代码的VM或JIT非常困难。使用JIT / VM推荐的快速类型(在本例中为整数)可能仍然是最好的,因为随着JIT和VM在发出更高效的本机指令方面变得更好,您的高级代码应该可以获得相关的性能提升修改

  2. 本机硬件(为什么第一级不完美):现在大多数处理器都有硬件浮点单元(支持浮点数和双精度数)。如果存在这样的硬件单元,浮点/双精度可能比整数快,除非还有硬件整数支持。使问题更加复杂的是,大多数CPU都具有某种形式的SIMD(单指令多数据)支持,如果数据类型足够小,则允许对操作进行矢量化(例如,通过在每个寄存器中添加2个而不是在一个指令中添加4个浮点数为4个双打中的每一个使用一个完整的寄存器)。这样可以允许处理使用较少位的数据类型比双精度快得多,但代价是精度。

  3. 优化速度需要详细了解这两个级别以及它们如何相互作用。即使优化内存使用也可能很棘手,因为VM可以选择以更大的占用空间来表示您的数据,原因是:浮点数可能占用VM代码中的8个字节,尽管这种可能性较小。所有这些使得优化几乎与可移植性相反。因此,再次使用VM推荐的“快速”数据类型会更好,因为这样可以在支持的设备上实现最佳性能平均值。

    即使在台式机上,这也不是一个糟糕的问题。是的,它们今天非常快,但如果你正在实现一个复杂的算法(例如,快速傅里叶变换),即使很小的优化也会对算法的运行时间产生巨大的影响。在任何情况下,你的问题“哪个更快:浮动或双打”的答案是“它取决于”:)

答案 7 :(得分:0)

我也对此感到疑惑并写了一个小测试:

#include <iostream>
#include <chrono>

template<typename numType>
void test(void)  {
    std::cout<< "Size of variable: " << sizeof(numType) << std::endl;
    numType array[20000];

    auto t1 = std::chrono::high_resolution_clock::now();
    // fill array
    for( numType& number : array ) {
        number = 1.0014535;
    }

    auto t2 = std::chrono::high_resolution_clock::now();

    // multiply each number with itself 10.000 times
    for( numType& number : array ) {
        for( int i=0; i < 10000 ; i++ )  {
            number *= number;
        }
    }

    auto t3 = std::chrono::high_resolution_clock::now();

    auto filltime = t2 - t1;
    auto calctime = t3 - t2;

    std::cout<< "Fill time: " << filltime.count() << std::endl;
    std::cout<< "Calc time: " << calctime.count() << std::endl;
}

int main(int argc, char* argv[]) {
    test<float>();
    test<double>();
}

我使用英特尔i7 3930k处理器上的GCC在Ubuntu 12.04 x64下运行并编译它

结果如下:

Size of variable: 4
Fill time: 69
Calc time: 694303

Size of variable: 8
Fill time: 76
Calc time: 693363

结果是可重复的。因此,double的内存分配需要稍长一些,但实际的计算时间却完全相同。


出于好奇,我还使用Visual Studio 2012在intel i7 920处理器上以发布模式在Windows 7 x64下运行并编译它

(时间的单位是不同的,所以不要将上面的结果与这些结果进行比较:它仅对内部比较有效)

Size of variable: 4
Fill time: 0
Calc time: 3200183

Size of variable: 8
Fill time: 0
Calc time: 3890223

结果是可重复的。

似乎在Windows上分配是即时的,也许是因为Linux在你使用它之前实际上并没有给你内存,而windows只是将它全部交给你,需要较少的系统调用。或者也许优化了任务。

这里双打的乘法比浮点数慢21.5%。与之前测试的差异可能是由于处理器不同(这至少是我最好的猜测)。