web-dev-qa-db-ja.com

フロートまたはダブル?

Arithimic(+-* /%)を実行する場合、doubleまたはfloatのどちらが速く、メモリ上の理由からfloatを使用するだけの価値があるでしょうか精度は問題ではありません。

これを考えても気兼ねなく呼んでください。私が使用しているフロートの量が大きくなっているのを見て、気になるだけです。

編集1:これがAndroidの下にある唯一の理由は、それが私がメモリが重要であると考える場所だからです;私はデスクトップ開発のためにこれを尋ねることさえしません。

29
ahodder

高速な演算についてはお勧めしませんが、floatの演算は、32ビット対doubleの64ビットであるため、高速になると思います。

6

両方のタイプの処理速度は、現在のCPUではほぼ同じです。

「許容できる結果を得るために必要な精度を使用してください。」

関連する質問がここSOで何度か尋ねられました これが1つです

編集:

速度に関しては、より新しいハードウェアでは、floatとdoubleの間に違いはありません。

これをチェックしてください article developer.Android.comから。

26
Nick Rolando

FloyoからのDalvikでのJIT(Just In Time)最適化(API 8以降)によるADT v21 lintメッセージでは、FloatではなくDoubleが推奨されました。

私はFloatMath.sinを使用していましたが、代わりにMath.sinが提案され、「問題の説明」コンテキストメニューの下に次のように表示されました。これは、trigだけでなく、doubleとfloatに関する一般的なメッセージのように読みます。

「Androidの以前のバージョンでは、フロートでの操作時のパフォーマンス上の理由から、Android.util.FloatMathを使用することをお勧めしました。ただし、最近のハードウェアでは、doubleはフロートと同じくらい高速です(メモリを多く消費します)。また、最近のバージョンのAndroidでは、 JITがJava.lang.Mathを最適化する方法が原因で、FloatMathは実際にはJava.lang.Mathを使用するよりも遅くなります。したがって、Froyo以上のみを対象とする場合は、FloatMathではなくMathを使用する必要があります。」

お役に立てれば。

15
phillxnet

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

浮動小数点の使用を避ける

経験則として、浮動小数点は、Android搭載デバイスでは整数よりも約2倍遅くなります。

速度に関しては、より新しいハードウェアでは、floatとdoubleの間に違いはありません。空間的には、doubleは2倍大きくなります。デスクトップマシンの場合と同様に、スペースが問題にならないと想定すると、浮動よりもdoubleの方が適しています。

また、整数の場合でも、一部のプロセッサにはハードウェア乗算がありますが、ハードウェア除算がありません。このような場合、整数の除算と係数の演算はソフトウェアで実行されます。ハッシュテーブルを設計している場合や、多くの計算を実行している場合は、何かを考える必要があります。

6
Dante

floatは32ビットまたは4バイトです

doubleは64ビットまたは8バイトです

そうそう、フロートは、Sun Java認定書によると、半分のサイズです。

4
dylan murphy

速度に関しては、より新しいハードウェアでは、floatとdoubleの間に違いはありません。

非常に安価なデバイスのFPUは限られているようで、floatはdoubleよりも高速です。私は現在、世界で最も安価なタブレットの1つとして販売されているCMXデバイスでテストしました。

  • 「float」テストコードは4.7秒かかります
  • 「double」の同じコードは6.6秒かかります

この質問は数回尋ねられました...

はい。答えはハードウェアの種類によって異なるためです。デスクトップコンピュータでは、doubleはfloatと同じ速度です。 FPUのないデバイス(WLANルーターハックに興味深い)では、フロートはダブルの2〜5倍高速です。また、32ビットFPUを備えたデバイス(産業および自動車アプリケーションでよく見られる)でさえ、最大100倍です。

この記事をチェックしてください...

記事の最後のセクションでは、使用するハードウェアデバイスの時間測定を100%確実に行う必要があると述べています。

3
Martin

Androidドキュメントの引用は、整数が高速演算に適していることを示しています。これは一見奇妙に思われますが、int対float対doubleを使用するアルゴリズムの速度は、いくつかのレイヤーに依存します。

  1. JITまたはVM:これらは数学演算をホストマシンのネイティブ命令セットに変換し、その変換はパフォーマンスに大きな影響を与える可能性があります。基盤となるハードウェアはプラットフォームごとに劇的に異なる可能性があるため、VMまたはすべてのケースで最適なコードを生成するJITを書くことは非常に困難です。おそらくJITを使用するのが最善です。/VMが推奨する高速タイプ(この場合は整数)。JITとVMがより効率的なネイティブ命令を生成するので、高レベルのコードは変更なしで関連するパフォーマンスの向上を得るはずです。

  2. ネイティブハードウェア(最初のレベルが完全ではない理由):最近のほとんどのプロセッサには、ハードウェアの浮動小数点ユニットがあります(これらは浮動小数点と倍精度をサポートしています)。そのようなハードウェアユニットが存在する場合、浮動小数点数/倍精度数は、ハードウェア整数のサポートもない限り、整数よりも高速になる可能性があります。問題を複雑にしているのは、ほとんどのCPUが何らかの形式のSIMD(単一命令複数データ)サポートを備えていることです。これにより、データタイプが十分に小さい場合に操作をベクトル化できます(たとえば、 4つのdoubleのそれぞれに1つの整数レジスタを使用します)。これにより、精度を犠牲にして、より少ないビットを使用するデータ型をdoubleよりも高速に処理できます。

速度を最適化するには、これらのレベルとそれらがどのように相互作用するかについての詳細な知識が必要です。 VMは他の理由でデータをより大きなフットプリントで表すことを選択できるため、メモリ使用の最適化でさえ注意が必要です。フロートがVMのコードで8バイトを占有する可能性があります。 。これらすべてにより、移植性の最適化とほぼ逆の最適化が行われます。そのため、ここでも、サポートされているデバイス全体で平均して最高のパフォーマンスが得られるため、VMの推奨「高速」データタイプを使用することをお勧めします。

これは、デスクトップであっても、決して悪い質問ではありません。はい、今日は非常に高速ですが、複雑なアルゴリズム(高速フーリエ変換など)を実装している場合、小さな最適化でもアルゴリズムの実行時間に多大な影響を与える可能性があります。いずれの場合も、「どちらが速いか:floatまたはdoubles」という質問への答えは「依存します」です:)

1
Andrew

私もこれについて疑問に思い、小さなテストを書きました:

#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>();
}

Intel 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のメモリ割り当てには少し時間がかかりますが、実際の計算時間はまったく同じです。


不思議なことに、私はWindows 7 x64でも実行し、Intel i7 920プロセッサのリリースモードでVisual Studio 2012を使用してコンパイルしました

(時間の単位が異なるため、上記の結果をこれらと比較しないでください。これは内部比較でのみ有効です)

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

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

結果は再現可能でした。

Windowsの割り当ては瞬時に行われるようです。おそらく、Linuxはメモリを使用するまで実際にはメモリを提供しないのです。または、割り当てが最適化されて離れている可能性があります。

Doubleの乗算は、floatの場合よりも21,5%遅くなります。前のテストとのこの違いは、おそらくプロセッサの違いによるものです(少なくとも私の推測では)。

0
Erik van Velzen