2010-03-19 4 views
16

Java의 기본 부동 소수점 유형은 double입니다. 2.5과 같은 상수를 프로그램에 하드 코딩하면 Java가 자동으로 이중으로 만듭니다. float 또는 int에 대한 연산을 수행 할 때 더 많은 정밀도의 이점을 얻을 수있는 경우 유형이 double으로 '승격'됩니다.왜 안드로이드 API에 너무 많은 수레가 있습니까?

하지만 Android API에서는 모든 것이 사운드 볼륨에서 직사각형 좌표로 이동하는 것으로 보입니다. 대부분의 도면에 사용 된 RectF 구조가 있습니다. F는 플로트 용입니다. 승진 복식을 (float)으로 자주 캐스팅하는 프로그래머에게는 꽤 고통스런 일입니다. 우리 모두는 자바 코드가 지저분하고 충분히 장황하다는데 동의하지 않습니까?

일반적으로 수치 연산 보조 프로세서 및 가속기는 내부 유형 중 하나에 해당하므로 Java에서 두 배를 선호합니다. 어떤 이유로 든 수레를 선호하는 Android의 Dalvik VM에 대해 뭔가 있습니까? 아니면 모든 수레가 API 디자인의 왜곡의 결과일까요?

+0

두 배가 처음으로 시작될 때 수레 또는 정수가 두 배로 승격되는 시점은 언제입니까? – Karu

답변

8

CPU에 따라 FPU (Floating Point Unit)가 없습니다. 따라서 FPU를 소프트웨어에서 에뮬레이션해야합니다. 이것은 Float가 Double보다 빠릅니다. 또는 장치에 FPU가있는 경우 Floats로 더 빠를 수도 있습니다.

+1

이것은 devs에서 올바른 이유에 가장 가깝습니다. 그것은 정말로 기억이 아닙니다. ARM에는 FPU가 없으며 32 비트 FPU를 사용하는 ARM도 있습니다. 64 비트 복식 에뮬레이션이 느립니다. –

+7

"fadden"(VM을 작성한 사람 중 하나)의 다른 대답이 가장 좋은 답변입니다. –

+0

정정 - 현대 장치의 수레 및 복식에 해당됩니다. –

7

유효하지 않은 숫자 (예 : 화면 오프셋)가 필요하지 않은 메트릭의 경우 float 대신 double을 사용하면 메모리가 비효율적입니다. 메모리 소비와 관련하여 효율성을 극대화하는 것은 거의 모든 리소스가 프리미엄 인 모바일 장치에서 매우 중요합니다. 그리고 수천 —에 의해 잠재적으로 할당 될 수있는 Rect —과 같은 객체를 처리 할 때 초과 비트를 줄이는 것이 분명히 중요합니다.

나는 다른 이유가 너무 :-)

3

이상한있다 확신합니다. 이 가이드의 성능을위한 설계는 ".... 데스크탑 시스템의 일반적인 관행은 자유롭게 부동 소수점을 사용하는 것입니다. 따라서"float "및"double "에 대한 모든 작업은 소프트웨어에서 수행됩니다 ... . "http://developer.android.com/guide/practices/design/performance.html#avoidfloat

이것은 의미가있을 수 있습니다 : ".... 지침은 특정 유형으로 무조건적으로 제한되지 않습니다. 예를 들어, 해석없이 32 비트 레지스터 값을 이동시키는 명령은 지정할 필요가 없습니다 ..... " at http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html

+1

나는 froyo에 대한 "성능을위한 설계"의 대부분을 다시 작성했습니다. Droid 및 Nexus One과 같은 현대 장치에는 부동 소수점 하드웨어가 있습니다. 즉 부동 소수점/복식의 나누기가 ints/longs의 나누기보다 빠릅니다 (하드웨어 정수 나누기가 없기 때문에). –

+1

Dalvik 바이트 코드 문서의 주석은 명령어 세트의 디자인과 코드 검증과 관련하여 더 많이 있습니다. 내부적으로 "정수 상수"0 또는 "부동 소수점 상수 0"을 사용하여 레지스터를로드하는지 여부는 관계가 없습니다. 그것은 단지 32 비트 값입니다. float 대 double 또는 performance와 관련이 없습니다. – fadden

1

로마가 맞다고 생각합니다. 그 이유는 주로 메모리 사용을 줄이려고하기 때문입니다. 궁극적 인 정밀도가 중요하지 않은 경우 숫자 변수에 필요한 메모리를 절반으로 줄이는 것을 고려하십시오.

캐스팅을 사용할 필요가 없음을 기억하십시오. 단순히 리터럴에 F를 붙이십시오 (2.5는 2.5f가됩니다). 컴파일러가 다음 대입을 수행 할만큼 영리한 지 여부는 잘 모르겠지만 그렇지 않을 경우 코드가 약간 더 효율적으로 작동합니다.

프로그램은 결과 부동 소수점 값을 저장하기 전에, 이중 후 행하는 주조 작업 기억, 실행시에,

float x = (float) 2.5; 

상기 제 경우

float x = 2.5f; 

을 고려한다.두 번째 경우 컴파일러는이 값을 부동 소수점으로 인식하므로 런타임에 double을 저장하는 것을 피할 수 있습니다 (일시적 일 수도 있음). 또한 캐스팅 연산을 피할 수 있습니다 (이미 float로 저장되어 있으므로).

+0

정말입니까? 방금 테스트했는데 두 버전 모두 동일한 바이트 코드를 생성합니다. 파든의 대답을보십시오. – Oliv

+0

@Oliv - 퇴색 한 후 나에게 대답 해 주었고, 나는 확신 할 수 없다는 것을 분명히했다. "컴파일러인지 모르겠다 ..." – Jimbugs

43

FPU가없는 장치에서는 단 정밀도 부동 소수점 연산이 배정도 부동 소수점 연산보다 훨씬 빠릅니다. 이 때문에 안드로이드 프레임 워크는 java.lang.Math 함수를 복제하는 FloatMath 클래스를 제공하지만 double 대신 float 인수를 사용합니다.

FPU가있는 최근 Android 장치에서 단 정밀도 및 배정 밀도 연산에 필요한 시간은 거의 동일하며 소프트웨어 구현보다 훨씬 빠릅니다. ("성능을위한 설계"페이지는 G1 용으로 작성되었으며 다양한 변경 사항을 반영하여 업데이트해야합니다.) "2.5f"또는 "(float) 2.5"를 쓰는 것은 중요하지 않습니다. 어느 쪽이든, javac은 단 정밀도 부동 소수점 상수를 원한다는 것을 알고 있으며, 이는 그것이 생성하는 것이다. 샘플 프로그램을 작성하고 생성 된 바이트 코드를 검사하여이를 검증 할 수 있습니다.

관련 문제