2013-02-28 92 views
34

在Android API的FloatMath的最新更新標有以下皮棉警告:使用FloatMath或Math和演員?

在老版本的Android,採用浮筒上操作時建議使用性能的原因android.util.FloatMath是 。然而,現代硬件雙打上的 與浮動一樣快(雖然它們會帶來更多內存),而在最近的Android版本中,由於JIT優化的方式,FloatMath實際上比使用java.lang.Math慢 java .lang.Math。因此,如果 僅針對Froyo及更高版本,則應使用Math而不是FloatMath。

還提到了here在最近的硬件上double和float的速度是相等的。

我在一個應用程序中使用了一些三角函數(目標函數爲Froyo和以上),但不需要高精度,所以我一直使用浮點數和FloatMath,並且沒有任何需要切換到雙打。
但是,「使用Math而不是FloatMath」 - 建議不會說如果float是所需結果,則使用哪一個。

總之,哪一個更好?

float foo = FloatMath.sin(bar); 

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

在一個側面說明,我只有一個Froyo的設備,所以我真的不能做我自己的任何適當的標杆。

作爲API級別22 FloatMath級的已棄用,取而代之的常規數學類的。

+0

我認爲你引用的文字表示如果float是所需的結果,則應該使用數學而不是floatmath和cast。 – 2013-02-28 19:17:34

+2

我會採用任何有關'int' /'float' /'double'相對性能的聲明來獲得一大片鹽。簡單地說,由於較小的緩存佔用量,「float」可能稍微快一點;在iPhone 3GS上,「float」顯着更快,因爲它可以使用NEON單元而不是較慢的VFP單元(NEON單元不支持雙倍);這可能是iDevice特有的。此外,自動矢量化JIT將自動受益'float'多於'double',因爲它可以將更多的數據放入每個向量寄存器中。 – 2013-03-28 20:23:49

+0

難道浮子都是作爲最新Android設備上的雙打存儲的嗎?! – Philip 2013-12-09 04:16:22

回答

14

正如你可以從下面的結果中看到,使用java.lang.Math的是彩車比雙打更快,比FloatMath更快。此外,FloatMath沒有.EXP()或.pow()API級別17.

之前在三星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 

無數據用於數學。罪對三星,因爲它已隨機決定忽略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

5

docs for FloatMath說:

數學程序,類似於數學中。 直接在浮點數值上執行計算,而不會產生雙向轉換的開銷。

和你的報價說:

使用android.util.FloatMath建議出於性能的考慮上彩車

操作時大概的FloatMath利益總是專門爲當你想要一個float,但這種好處現在已被否定。

所以使用:

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

同時認爲,如果性能是如此重要,你需要擔心這一點,也許改用double畢竟是保證(不招致轉換成本)。

+0

如果現在運行的雙打或浮動沒有區別,仍然可以將浮動轉換爲雙打,反之亦然。因此使用Math將會導致從一種類型轉換爲另一種類型,並且FloatMath將直接在浮動上運行。那麼爲什麼使用Math更好? – Egor 2013-02-28 19:30:39

+0

某些數學方法將雙打作爲參數,因此也會發生一些隱式投射。 – Jave 2013-02-28 19:31:42

+3

@Egor我不知道爲什麼使用'Math'比所提到的更好的細節,我只是說文檔和lint警告似乎暗示你應該使用'Math'來代替'FloatMath'即使在考慮轉換成本時也是如此。另外,除非空間有問題,否則一般只使用'double'而不是'float' [推薦](http://developer.android.com/training/articles/perf-tips.html#AvoidFloat)。 – kabuko 2013-02-28 19:38:34

-1

如果性能是重要的,那麼你可能不想浪費投,並從double小號每次計算的東西的時間。

據我瞭解,在老硬件花車比雙打快,因此你需要一個數學庫浮動。現在,「在現代硬件雙打一樣快,因爲浮動」,因此,你應該使用默認的Math與雙打。

如果你的應用程序的值是浮點數(例如,由於內存消耗)對你來說很重要,你應該繼續使用FloatMath,因爲如果你使用它很多,float foo = (float) Math.sin(bar);會變得很煩人。

2

我只是在尋找到相同的問題,最近,發現這個bug report在這個問題上。該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 

如果按照documentation changes在AOSP樹,你會看到hereMath功能是首選FloatMath上與JIT,這基本上是從升級Froyo(2.2)和高達機器人的任何版本。