Xamarin은 Android에서 모노 구현과 C # 컴파일 된 앱이 Java 코드보다 빠르다고 주장했습니다. 다른 안드로이드 플랫폼에서 매우 유사한 Java 및 C # 코드에서 실제 벤치 마크를 수행하여 그러한 주장을 확인하고 코드와 결과를 게시 할 수 있습니까?
2013 년 6 월 18 일 추가됨
답이 없었으며 다른 사람들이 수행 한 벤치 마크를 찾을 수 없으므로 내 테스트를하기로 결정했습니다. 불행히도 내 질문은 "잠긴"상태로 유지되므로 답변으로 게시 할 수 없으며 질문 만 편집하십시오. 이 질문을 다시 열려면 투표하십시오. C #의 경우 Xamarin을 사용했습니다 .Android Ver. 4.7.09001 (베타). 소스 코드, 테스트 및 컴파일 된 APK 패키지에 사용 된 모든 데이터는 GitHub에 있습니다.
자바 : https://github.com/gregko/TtsSetup_Java
C # : https://github.com/gregko/TtsSetup_C_sharp
누군가 다른 장치 또는 에뮬레이터에서 테스트를 반복하고 싶다면 결과도 배우고 싶습니다.
내 테스트 결과
문장 추출기 클래스를 C # (@ Voice Aloud Reader 앱에서)으로 포팅하고 영어, 러시아어, 프랑스어, 폴란드어 및 체코 어로 10 개의 HTML 파일에서 테스트를 실행했습니다. 각 실행은 10 개의 파일 모두에서 5 번 수행되었으며 3 개의 서로 다른 장치와 하나의 에뮬레이터의 총 시간이 아래에 게시되어 있습니다. 디버깅을 사용하지 않고 "릴리스"빌드 만 테스트했습니다.
HTC Nexus One Android 2.3.7 (API 10)-CyanogenMod ROM
Java : 총 시간 (5 회) : 12361ms, 파일 읽기 총량 : 13304ms
C # : 총 시간 (5 회) : 17504ms, 파일 읽기 총량 : 17956ms
Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15)-CyanogenMod ROM
Java : 총 시간 (5 회) : 8947ms, 파일 읽기 총계 : 9186ms
C # : 총 시간 (5 회) : 9884ms, 파일 읽기 총량 : 10247ms
Samsung GT-N7100 (Android 4.1.1 JellyBean, API 16)-Samsung ROM
Java : 총 시간 (5 회) : 9742ms, 파일 읽기 총계 : 10111ms
C # : 총 시간 (5 회) : 10459ms, 파일 읽기 총량 : 10696ms
에뮬레이터-인텔 (Android 4.2, API 17)
Java : 총 시간 (5 회) : 2699ms, 파일 읽기 총계 : 3127ms
C # : 총 시간 (5 회) : 2049ms, 파일 읽기 총량 : 2182ms
에뮬레이터-인텔 (Android 2.3.7, API 10)
Java : 총 시간 (5 회) : 2992ms, 파일 읽기 총계 : 3591ms
C # : 총 시간 (5 회) : 2049ms, 파일 읽기 총량 : 2257ms
에뮬레이터-Arm (Android 4.0.4, API 15)
Java : 총 시간 (5 회) : 41751ms, 파일 읽기 총계 : 43866ms
C # : 총 시간 (5 회) : 44136ms, 파일 읽기 총량 : 45109ms
간단한 토론
내 테스트 코드에는 주로 텍스트 파싱, 대체 및 Regex 검색이 포함되어 있으며 다른 코드 (예 : 더 많은 숫자 연산)의 경우 결과가 다를 수 있습니다. ARM 프로세서가 장착 된 모든 장치에서 Java는 Xamarin C # 코드보다 성능이 우수합니다. 가장 큰 차이점은 Android 2.3에서 C # 코드가 약 1에서 실행되는 것입니다. Java 속도의 70 %
Intel HAX 기술을 사용하는 Intel 에뮬레이터에서 에뮬레이터는 빠른 virt 모드로 실행됩니다. Xamarin C # 코드는 Java보다 훨씬 빠르게 샘플 코드를 약 1.35 배 빠르게 실행합니다. 아마도 모노 가상 머신 코드와 라이브러리가 ARM보다 인텔에서 훨씬 더 최적화되어 있습니까?
2013 년 7 월 8 일 수정
방금 Oracle VirtualBox에서 실행되는 Genymotion Android 에뮬레이터를 설치했으며 다시 ARM 프로세서를 에뮬레이션하지 않고 기본 Intel 프로세서를 사용합니다. Intel HAX 에뮬레이터와 마찬가지로 C #도 여기서 훨씬 더 빠르게 실행됩니다. 내 결과는 다음과 같습니다.
Genymotion 에뮬레이터-Intel (Android 4.1.1, API 16)
Java : 총 시간 (5 회) : 2069ms, 파일 읽기 총계 : 2248ms
C # : 총 시간 (5 회) : 1543ms, 파일 읽기 총계 : 1642ms
그런 다음 Xamarin.Android 베타 버전 4.7.11에 대한 업데이트가 모노 런타임의 일부 변경 사항을 언급하는 릴리스 노트와 함께 있음을 알았습니다. 일부 ARM 장치를 신속하게 테스트하기로 결정했으며 놀랍게도 C # 숫자가 향상되었습니다.
BN Nook XD +, ARM (Android 4.0)
Java : 총 시간 (5 회) : 8103ms, 파일 읽기 총량 : 8569ms
C # : 총 시간 (5 회) : 7951ms, 파일 읽기 총량 : 8161ms
와! C #이 이제 Java보다 낫습니까? Galaxy Note 2에서 테스트를 반복하기로 결정했습니다.
삼성 Galaxy Note 2-ARM (Android 4.1.1)
Java : 총 시간 (5 회) : 9675ms, 파일 읽기 총계 : 10028ms
C # : 총 시간 (5 회) : 9911ms, 파일 읽기 총계 : 10104ms
여기서 C #은 약간 느리게 보이지만이 숫자로 인해 잠시 멈추었습니다. Note 2의 프로세서 속도가 더 빠르더라도 Nook HD +보다 시간이 더 긴 이유는 무엇입니까? 답 : 절전 모드. Nook에서는 비활성화되었으며, 참고 2에서는 활성화되었습니다. 절전 모드를 비활성화 한 상태에서 테스트하기로 결정했습니다 (활성화 된 경우 프로세서 속도도 제한됨).
Samsung Galaxy Note 2-ARM (Android 4.1.1), 절전 기능 비활성화
Java : 총 시간 (5 회) : 7153ms, 파일 읽기 총량 : 7459ms
C # : 총 시간 (5 회) : 6906ms, 파일 읽기 총량 : 7070ms
놀랍게도 C #은 ARM 프로세서의 Java보다 약간 빠릅니다. 큰 개선!
2013 년 7 월 12 일 수정
우리 모두는 속도를 위해 네이티브 코드를 능가하는 것이 없으며 Java 또는 C #에서 문장 스플리터의 성능에 만족하지 못 했으므로 특히 개선해야합니다 (따라서 느리게 만들어야 함). C ++로 다시 작성하기로 결정했습니다. 다음은 절전 모드가 비활성화 된 상태에서 Galaxy Note 2의 기본 속도와 Java 속도를 비교 한 것입니다 (예 : 다른 이유로 이전 테스트보다 작은 파일 세트).
Java : 총 시간 (5 회) : 3292ms, 파일 읽기 총계 : 3454ms
기본 엄지 : 총 시간 (5 회) : 537ms, 파일 읽기 총 시간 : 657ms
네이티브 암 : 총 시간 (5 회) : 458ms, 파일 읽기 총계 : 587ms
내 특정 테스트의 경우 네이티브 코드가 Java보다 6 ~ 7 배 빠릅니다. 주의 사항 : Android에서 std :: regex 클래스를 사용할 수 없으므로 단락 나누기 또는 html 태그를 검색하는 고유 한 루틴을 작성해야했습니다. 정규식을 사용하는 PC에서 동일한 코드에 대한 초기 테스트는 Java보다 약 4-5 배 빠릅니다.
휴! char * 또는 wchar * 포인터를 사용하여 원시 메모리를 다시 깨우면 20 년이 더 젊어졌습니다. :)
2013 년 7 월 15 일 수정
Dot42로 훨씬 더 나은 결과를 얻으려면 2013 년 7 월 30 일의 수정 사항으로 아래를 참조하십시오.
약간의 어려움으로 C # 테스트를 Android의 또 다른 C # 플랫폼 인 Dot42 (버전 1.0.1.71 베타)로 이식 할 수있었습니다. 예비 결과에 따르면 Intel Android 에뮬레이터에서 Dot42 코드가 Xamarin C # (v. 4.7.11)보다 약 3 배 (3 배) 느립니다. 한 가지 문제는 Dot42의 System.Text.RegularExpressions 클래스에 Xamarin 테스트에서 사용한 Split () 함수가 없으므로 대신 Java.Util.Regex 클래스를 사용했으며 Java.Util.Regex.Pattern.Split () 코드의 특정 위치에는이 작은 차이가 있습니다. 그래도 큰 문제는 아닙니다. Dot42는 Dalvik (DEX) 코드로 컴파일되므로 기본적으로 Android에서 Java와 협력하며 Xamarin과 같이 C #에서 Java로 비싼 상호 운용성이 필요하지 않습니다.
비교를 위해 ARM 디바이스에서도 테스트를 실행합니다. 여기서 Dot42 코드는 Xamarin C #보다 "배속"만 2 배 느립니다. 내 결과는 다음과 같습니다.
HTC Nexus One Android 2.3.7 (ARM)
Java : 총 시간 (5 회) : 12187ms, 파일 읽기 총량 : 13200ms
Xamarin C # : 총계 총 시간 (5 회 실행) : 13935ms, 파일 읽기 총계 : 14465ms
Dot42 C # : 총 시간 (5 회) : 26000ms, 파일 읽기 총량 : 27168ms
삼성 Galaxy Note 2, Android 4.1.1 (ARM)
Java : 총 시간 (5 회) : 6895ms, 파일 읽기 총량 : 7275ms
Xamarin C # : 총 시간 (5 회) : 6466ms, 파일 읽기 총량 : 6720ms
Dot42 C # : 총 시간 (5 회) : 11185ms, 파일 읽기 총량 : 11843ms
인텔 에뮬레이터, Android 4.2 (x86)
Java : 총 시간 (5 회) : 2389ms, 파일 읽기 총계 : 2770ms
Xamarin C # : 총 시간 (5 회) : 1748ms, 파일 읽기 총량 : 1933ms
Dot42 C # : 총 시간 (5 회) : 5150ms, 파일 읽기 총량 : 5459ms
저에게는 Xamarin C #이 최신 ARM 장치에서 Java보다 약간 빠르며 이전 Nexus One에서는 약간 느리다는 점도 흥미로 웠습니다. 누구나이 테스트를 실행하려면 알려 주시면 GitHub에서 소스를 업데이트하겠습니다. Intel 프로세서가 장착 된 실제 Android 장치에서 결과를 보는 것이 특히 흥미로울 것입니다.
2013 년 7 월 26 일 업데이트
최신 Xamarin.Android 4.8 및 오늘 출시 된 dot42 1.0.1.72 업데이트로 벤치 마크 앱으로 다시 컴파일 된 빠른 업데이트만으로 이전에보고 된 결과와 큰 차이가 없습니다.
2013 년 7 월 30 일 업데이트-dot42에 대한 더 나은 결과
Java 코드의 Robert 's (dot42 제조업체에서) 포트를 사용하여 Dot42를 다시 테스트했습니다. Xamarin을 위해 처음 수행 된 C # 포트에서 ListArray와 같은 일부 고유 Java 클래스를 C # 고유의 List 클래스로 대체했습니다. Robert는 Dot42 소스 코드를 가지고 있지 않으므로 Java에서 다시 포팅하여 원래 Java 클래스를 사용했습니다. Dot42에 도움이되는 그러한 장소는 Xamarin과 같이 Mono가 아닌 Java와 같은 Dalvik VM에서 실행되기 때문에 추측합니다. 이제 Dot42 결과가 훨씬 좋습니다. 내 테스트의 로그는 다음과 같습니다.
2013 년 7 월 30 일-Dot42 C #에서 더 많은 Java 클래스로 Dot42 테스트
인텔 에뮬레이터, 안드로이드 4.2
Dot42, StringBuilder.Replace ()를 사용하는 Greg의 코드 (Xamarin에서와 같이) :
총 시간 (5 회 실행) : 3646ms, 파일 읽기 총계 : 3830msDot42, String.Replace ()를 사용하는 Greg의 코드 (Java 및 Robert의 코드에서와 같이) :
총 시간 (5 회 실행) : 3027ms, 파일 읽기 총계 : 3206msDot42, Robert의 코드 :
총 시간 (5 회) : 1781ms, 파일 읽기 총 시간 : 1999msXamarin :
총 시간 (5 회) : 1373ms , 파일 읽기 총 시간 : 1505msJava :
총 시간 (5 회) : 1841ms, 파일 읽기 총계 : 2044msARM, Samsung Galaxy Note 2, 절전, Android 4.1.1
Dot42, StringBuilder.Replace ()를 사용하는 Greg의 코드 (Xamarin에서와 같이) :
총 시간 (5 회 실행) : 10875ms, 파일 읽기 총계 : 11280msDot42, String.Replace ()를 사용하는 Greg의 코드 (Java 및 Robert의 코드에서와 같이) :
총 시간 (5 회 실행) : 9710ms, 파일 읽기 총계 : 10097msDot42, Robert 's Code :
총 시간 (5 회) : 6279ms, 파일 읽기 총량 : 6622msXamarin :
총 시간 (5 회) : 6201ms , 파일 읽기 총량 : 6476msJava :
총 시간 (5 회) : 7141ms, 파일 읽기 총량 : 7479ms
나는 아직도 Dot42가 갈 길이 멀다고 생각한다. Java와 같은 클래스 (예 : ArrayList)가 있고 성능이 좋으면 Java에서 C #으로 코드를 포팅하는 것이 약간 쉬워집니다. 그러나 이것은 내가 많이하지 않을 것입니다. 오히려 네이티브 C # 클래스 (예 : List)를 사용하는 기존 C # 코드 (라이브러리 등)를 사용하고 싶습니다. 이는 현재 dot42 코드에서 느리게 수행되며 Xamarin에서는 매우 잘 수행됩니다.
그렉