2013-02-28 33 views
34

Trong bản cập nhật mới nhất của API Android FloatMath được đánh dấu bằng các lint-cảnh báo sau đây:Sử dụng FloatMath hoặc Math và một diễn viên?

Trong các phiên bản Android cũ hơn, sử dụng android.util.FloatMath là khuyến khích cho lý do hiệu suất khi hoạt động trên phao nổi. Tuy nhiên, trên đôi phần cứng hiện đại cũng nhanh như phao (mặc dù chúng mất bộ nhớ), và trong các phiên bản gần đây của Android, FloatMath thực sự là chậm hơn sử dụng java.lang.Math do cách JIT tối ưu hóa java .lang.Math. Do đó, bạn nên sử dụng Toán thay vì FloatMath nếu bạn chỉ nhắm mục tiêu Froyo trở lên.

Nó cũng được đề cập đến here đôi và phao bằng tốc độ trên phần cứng gần đây.

Tôi đang sử dụng một số phép lượng giác trong một ứng dụng tôi hiện đang làm việc (nhắm mục tiêu Froyo và ở trên), nhưng độ chính xác cao là không cần thiết, vì vậy tôi đã sử dụng phao và FloatMath cho đến nay, và không cần bất cứ điều gì chuyển sang tăng gấp đôi.
Tuy nhiên, "sử dụng Math trên FloatMath" -khuyến nghị không cho biết nên sử dụng cái nào nếu phao là kết quả mong muốn.

Vì vậy, trong ngắn hạn; cái nào là thích hợp hơn?

float foo = FloatMath.sin(bar); 

hoặc

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

Trên một mặt lưu ý, tôi chỉ có một Froyo-thiết bị, vì vậy tôi thực sự không thể làm bất cứ điểm chuẩn thích hợp trên của riêng tôi.

Ở cấp API 22 lớp FloatMath đã không còn được ưu tiên cho lớp Math thông thường.

+0

Tôi nghĩ rằng văn bản bạn trích dẫn có nghĩa là nếu float là kết quả mong muốn, bạn nên sử dụng toán học thay vì floatmath và cast. –

+2

Tôi lấy bất kỳ yêu cầu nào về hiệu suất tương đối của 'int' /' float'/'double' với một lượng muối rất lớn. 'float' có thể hơi nhanh hơn đơn giản chỉ vì dấu chân bộ nhớ cache nhỏ hơn và trên iPhone 3GS,' float' là * đáng kể * nhanh hơn vì nó có thể sử dụng đơn vị NEON thay vì đơn vị VFP chậm hơn (đơn vị NEON không hỗ trợ tăng gấp đôi); điều này có thể là iDevice cụ thể. Ngoài ra, một JIT tự động vector hóa sẽ tự động được hưởng lợi 'float' nhiều hơn' double' đơn giản bởi vì nó có thể phù hợp hơn với chúng trong mỗi thanh ghi vector. –

+0

Có thể nào các phao nổi được lưu trữ trên các thiết bị Android mới nhất? – Philip

Trả lời

14

Như bạn có thể thấy từ kết quả dưới đây, sử dụng java.lang.Math nhanh hơn cho phao hơn là gấp đôi và nhanh hơn FloatMath. Hơn nữa, không có FloatMath .exp() hoặc .pow() trước khi cấp độ API 17.

Trên Samsung GT_i9295 (4.2.2), 2^24 chu kỳ

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 

Không có dữ liệu cho môn Toán. tội lỗi trên samsung vì nó đã ngẫu nhiên quyết định bỏ qua Log.d()> :(

trên HTC Hero_HT99VL (2.3.7), 2^12 chu kỳ

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() và .hypot() yêu cầu cấp API 17

5

Các docs for FloatMath nói:

Math thói quen tương tự như tìm thấy trong Math. Thực hiện tính toán trên giá trị phao trực tiếp mà không làm tăng chi phí chuyển đổi đến và từ gấp đôi.

và báo giá của bạn nói:

sử dụng android.util.FloatMath được khuyến khích cho lý do hiệu suất khi hoạt động trên phao nổi

Có lẽ lợi ích của FloatMath luôn đặc biệt cho khi bạn muốn có một số float, nhưng lợi ích này hiện đã bị từ chối.

Vì vậy, sử dụng:

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

Cũng xem xét rằng nếu hiệu suất là rất quan trọng mà bạn cần phải lo lắng về vấn đề này, có thể chuyển sang double được bảo hành sau khi tất cả (như không phải chịu chi phí chuyển đổi).

+0

Nếu không có sự khác biệt trong hoạt động tăng gấp đôi hoặc nổi ngày nay, vẫn có thể được trên không của chuyển đổi nổi để tăng gấp đôi và ngược lại.Vì vậy, việc sử dụng Math sẽ phải chuyển đổi từ kiểu này sang kiểu khác và FloatMath sẽ hoạt động trực tiếp trên float. Vậy tại sao sử dụng Toán học lại tốt hơn? – Egor

+0

một số phương thức toán học có tính nhân đôi làm đối số, do đó, cũng có một số diễn xuất tiềm ẩn đang diễn ra. – Jave

+3

@Egor Tôi không biết chi tiết chính xác lý do tại sao sử dụng 'Math' tốt hơn những gì được đề cập, tất cả những gì tôi nói là cảnh báo tài liệu và lint dường như ngụ ý rằng bạn nên sử dụng' Math' trên 'FloatMath' ngay cả khi xem xét chi phí chuyển đổi. Ngoài ra, chỉ cần sử dụng 'double' thay vì' float' nói chung là [được khuyến nghị] (http://developer.android.com/training/articles/perf-tips.html#AvoidFloat) trừ khi không gian là một vấn đề. – kabuko

-1

Nếu hiệu suất là quan trọng, thì có thể bạn không muốn lãng phí thời gian để truyền đến và đi từ double mỗi khi bạn tính toán điều gì đó.

Như tôi đã hiểu, trên các phiến phần cứng cũ hơn nhanh hơn gấp đôi, do đó bạn cần thư viện Toán cho phao. Bây giờ, "trên đôi phần cứng hiện đại chỉ nhanh như phao", do đó bạn nên sử dụng mặc định Math với tăng gấp đôi.

Nếu điều quan trọng đối với ứng dụng của bạn là các giá trị là nổi (ví dụ, do tiêu thụ bộ nhớ), bạn nên tiếp tục sử dụng FloatMath, vì float foo = (float) Math.sin(bar); sẽ trở nên khó chịu nếu bạn sử dụng nó rất nhiều.

2

Tôi vừa xem xét cùng một vấn đề gần đây và tìm thấy số này bug report về sự cố. Các Math chức năng tốt hơn các FloatMath những bởi một bậc, như thể hiện trên các báo dưới đây:

Sử dụng DDMS, tôi cấu hình mã trong câu hỏi. Mỗi chức năng dưới đây được gọi là hơn 100x.

 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 

Nếu bạn làm theo các documentation changes trong cây AOSP bạn sẽ thấy rằng hereMath chức năng được ưa thích để FloatMath trên các phiên bản của Android với một JIT, mà về cơ bản là bất cứ điều gì từ Froyo (2.2) trở lên.

Các vấn đề liên quan