ใครบ้างมีเกณฑ์มาตรฐาน (รหัส & ผลลัพธ์) เปรียบเทียบประสิทธิภาพของแอพ Android ที่เขียนใน Xamarin C # และ Java [ปิด]


544

ฉันพบว่า Xamarin อ้างว่าการใช้งานโมโนบน Android และแอพที่รวบรวมด้วย C # นั้นเร็วกว่าโค้ด Java ใครบ้างที่มีการวัดประสิทธิภาพจริง ๆ บนโค้ด Java และ C # ที่คล้ายกันมากบนแพลตฟอร์ม Android ที่แตกต่างกันเพื่อตรวจสอบการอ้างสิทธิ์ดังกล่าวสามารถโพสต์โค้ดและผลลัพธ์ได้หรือไม่

เพิ่มเมื่อวันที่ 18 มิถุนายน 2013

เนื่องจากไม่มีคำตอบและไม่สามารถหามาตรฐานดังกล่าวที่ทำโดยผู้อื่นได้ตัดสินใจทำการทดสอบของฉันเอง น่าเสียดายที่คำถามของฉันยังคง "ถูกล็อก" ดังนั้นฉันจึงไม่สามารถโพสต์สิ่งนี้เป็นคำตอบได้เพียงแก้ไขคำถามเท่านั้น โปรดลงคะแนนเพื่อเปิดคำถามนี้อีกครั้ง สำหรับ C # ฉันใช้ Xamarin.Android Ver 4.7.09001 (เบต้า) ซอร์สโค้ดข้อมูลทั้งหมดที่ฉันใช้สำหรับการทดสอบและรวบรวมแพ็คเกจ APK อยู่ใน GitHub:

Java: https://github.com/gregko/TtsSetup_Java

ค#: https://github.com/gregko/TtsSetup_C_sharp

หากมีคนต้องการทดสอบซ้ำบนอุปกรณ์หรือโปรแกรมจำลองอื่น ๆ ฉันก็สนใจที่จะเรียนรู้ผลลัพธ์เช่นกัน

ผลลัพธ์จากการทดสอบของฉัน

ฉันโอนย้ายคลาสตัวแยกประโยคเป็น C # (จากแอป @Voice Aloud Reader) ของฉันและรันการทดสอบบางไฟล์ในไฟล์ HTML 10 ไฟล์เป็นภาษาอังกฤษรัสเซียฝรั่งเศสโปแลนด์และเช็ก การดำเนินการแต่ละครั้งมีการดำเนินการ 5 ครั้งในไฟล์ทั้ง 10 ไฟล์และเวลารวมสำหรับอุปกรณ์ต่าง ๆ 3 ตัวและตัวจำลองหนึ่งตัวจะถูกโพสต์ไว้ด้านล่าง ฉันทดสอบบิลด์ "Release" เท่านั้นโดยไม่เปิดใช้งานการดีบัก

HTC Nexus One Android 2.3.7 (API 10) - CyanogenMod ROM

Java: เวลาทั้งหมด (5 รัน): 12361 ms, รวมไฟล์ที่อ่านได้: 13304 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 17504 ms, รวมการอ่านไฟล์: 17956 ms

Samsung Galaxy S2 SGH-I777 (Android 4.0.4, API 15) - CyanogenMod ROM

Java: เวลาทั้งหมด (5 รัน): 8947 มิลลิวินาที, รวมไฟล์ที่อ่านได้: 9186 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 9884 ms, รวมการอ่านไฟล์: 10247 ms

Samsung GT-N7100 (Android 4.1.1 JellyBean, API 16) - Samsung ROM

Java: เวลาทั้งหมด (5 รัน): 9742 ms, รวมไฟล์ที่อ่านได้: 10111 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 10459 ms, รวมการอ่านไฟล์: 10696 ms

Emulator - Intel (Android 4.2, API 17)

Java: เวลาทั้งหมด (5 รัน): 2699 ms, รวมไฟล์ที่อ่านได้: 3127 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 2049 ms, รวมไฟล์ที่อ่านได้: 2182 ms

Emulator - Intel (Android 2.3.7, API 10)

Java: เวลาทั้งหมด (5 รัน): 2992 ms, รวมไฟล์ที่อ่านได้: 3591 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 2049 ms, รวมไฟล์ที่อ่านได้: 2257 ms

Emulator - Arm (Android 4.0.4, API 15)

Java: เวลาทั้งหมด (5 รัน): 41751 ms, รวมไฟล์ที่อ่านได้: 43866 ms

C #: เวลารวมทั้งหมด (5 การวิ่ง): 44136 ms, รวมการอ่านไฟล์: 45109 ms

การอภิปรายสั้น ๆ

รหัสทดสอบของฉันมีการแยกวิเคราะห์ข้อความเป็นส่วนใหญ่การแทนที่และการค้นหา Regex อาจเป็นรหัสอื่น ๆ (เช่นการดำเนินการเป็นตัวเลขมากกว่า) ผลลัพธ์จะแตกต่างกัน ในอุปกรณ์ทั้งหมดที่มีโปรเซสเซอร์ ARM, Java ทำได้ดีกว่ารหัส Xamarin C # ความแตกต่างที่ใหญ่ที่สุดอยู่ภายใต้ Android 2.3 ซึ่งรหัส C # ทำงานที่ประมาณ 70% ของความเร็ว Java

บนตัวเลียนแบบ Intel (ด้วยเทคโนโลยี Intel HAX ตัวเลียนแบบทำงานในโหมด virt รวดเร็ว) รหัส Xamarin C # จะรันโค้ดตัวอย่างของฉันเร็วกว่า Java - เร็วขึ้นประมาณ 1.35 เท่า บางทีโค้ดและไลบรารีเครื่องเสมือนของ Mono นั้นได้รับการปรับให้เหมาะสมกับ Intel มากกว่า ARM หรือไม่?

แก้ไข 8 กรกฎาคม 2013

ฉันเพิ่งติดตั้งตัวจำลอง Genymotion Android ซึ่งทำงานใน Oracle VirtualBox และอีกครั้งอันนี้ใช้หน่วยประมวลผล Intel ดั้งเดิมไม่ใช่การจำลองหน่วยประมวลผล ARM เช่นเดียวกับ Intel HAX emulator, C # ทำงานที่นี่เร็วกว่ามาก นี่คือผลลัพธ์ของฉัน:

เครื่องมือจำลองจีโนม - Intel (Android 4.1.1, API 16)

Java: เวลาทั้งหมด (5 รัน): 2069 ms, รวมไฟล์ที่อ่านได้: 2248 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 1543 ms, รวมไฟล์ที่อ่านได้: 1642 ms

ฉันสังเกตเห็นว่ามีการอัพเดท Xamarin.Android beta รุ่น 4.7.11 พร้อมด้วยบันทึกประจำรุ่นที่กล่าวถึงการเปลี่ยนแปลงบางอย่างในรันไทม์ Mono เช่นกัน ตัดสินใจที่จะทดสอบอุปกรณ์ ARM อย่างรวดเร็วและแปลกใจใหญ่ - ปรับปรุงหมายเลข C #:

BN Nook XD +, ARM (Android 4.0)

Java: เวลาทั้งหมด (5 รัน): 8103 ms, รวมไฟล์ที่อ่านได้: 8569 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 7951 ms, รวมไฟล์อ่าน: 8161 ms

ว้าว! ตอนนี้ C # ดีกว่า Java ใช่ไหม ตัดสินใจที่จะทดสอบซ้ำบน Galaxy Note 2 ของฉัน:

Samsung Galaxy Note 2 - ARM (Android 4.1.1)

Java: เวลารวมทั้งหมด (5 วิ่ง): 9675 ms, โดยมีการอ่านไฟล์ทั้งหมด: 10028 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 9911 ms, รวมไฟล์ที่อ่านได้: 10104 ms

ที่นี่ C # ดูเหมือนว่าจะช้าลงเล็กน้อยเท่านั้น แต่ตัวเลขเหล่านี้ทำให้ฉันหยุดชั่วคราว: ทำไมเวลานานกว่า Nook HD + ถึงแม้ว่า Note 2 จะมีโปรเซสเซอร์ที่เร็วกว่า? คำตอบ: โหมดประหยัดพลังงาน ในนุ๊กมันถูกปิดการใช้งานในหมายเหตุ 2 - เปิดใช้งาน ตัดสินใจที่จะทดสอบด้วยโหมดประหยัดพลังงานถูกปิดการใช้งาน (เช่นเดียวกับที่เปิดใช้งานและยัง จำกัด ความเร็วโปรเซสเซอร์):

Samsung Galaxy Note 2 - ARM (Android 4.1.1) ปิดการใช้งานการประหยัดพลังงาน

Java: เวลาทั้งหมด (5 รัน): 7153 ms, รวมไฟล์ที่อ่านได้: 7459 ms

C #: เวลารวมทั้งหมด (5 วิ่ง): 6906 ms, รวมการอ่านไฟล์: 7070 ms

ตอนนี้น่าแปลกใจที่ C # นั้นเร็วกว่า Java บนโปรเซสเซอร์ ARM เล็กน้อยเช่นกัน การปรับปรุงครั้งใหญ่!

แก้ไข 12 กรกฎาคม 2556

เราทุกคนรู้ว่าไม่มีอะไรเต้นรหัสพื้นเมืองสำหรับความเร็วและฉันไม่พอใจกับประสิทธิภาพของตัวแยกประโยคใน Java หรือ C # โดยเฉพาะอย่างยิ่งที่ฉันต้องปรับปรุงมัน (และทำให้ช้าลง) ตัดสินใจที่จะเขียนใหม่ใน C ++ นี่คือไฟล์เล็ก ๆ (เช่นชุดไฟล์ที่เล็กกว่าการทดสอบก่อนหน้านี้ด้วยเหตุผลอื่น ๆ ) เปรียบเทียบความเร็วของ native กับ Java บน Galaxy Note 2 ของฉันโดยที่โหมดประหยัดพลังงานถูกปิดใช้งาน:

Java: เวลาทั้งหมด (5 รัน): 3292 ms, โดยรวมไฟล์ที่อ่านได้: 3454 ms

เนี้ยบทั่วไป: เวลาทั้งหมด (5 วิ่ง): 537 มิลลิวินาทีโดยรวมการอ่านไฟล์: 657 มิลลิวินาที

แขนพื้นเมือง: ผลรวมทั้งหมด (5 รอบ): 458 มิลลิวินาที, รวมไฟล์ที่อ่านได้: 587 มิลลิวินาที

ดูเหมือนว่าสำหรับการทดสอบเฉพาะของฉันโค้ดเนทีฟคือเร็วกว่า Java 6-7 เท่า Caveat: ไม่สามารถใช้ std :: regex class บน Android ได้ดังนั้นจึงต้องเขียนกิจวัตรพิเศษของตัวเองเพื่อค้นหาการแบ่งย่อหน้าหรือแท็ก html การทดสอบเริ่มต้นของรหัสเดียวกันบนพีซีโดยใช้ regex นั้นเร็วกว่า Java ประมาณ 4 ถึง 5 เท่า

วุ้ย ปลุกความทรงจำใหม่ด้วยพอยน์เตอร์ char * หรือ wchar * อีกครั้งฉันก็อายุน้อยกว่า 20 ปีทันที! :)

แก้ไขวันที่ 15 กรกฎาคม 2556

(โปรดดูด้านล่างพร้อมการแก้ไขของ 7/30/2556 เพื่อผลลัพธ์ที่ดียิ่งขึ้นด้วย Dot42)

ฉันจัดการพอร์ตการทดสอบ C # ของฉันไปยัง Dot42 (รุ่น 1.0.1.71 เบต้า) ซึ่งเป็นแพลตฟอร์ม C # อีกอันสำหรับ Android ผลลัพธ์เบื้องต้นแสดงว่ารหัส Dot42 นั้นช้ากว่า Xamarin C # (v. 4.7.11) ประมาณ 3 เท่า (3 เท่า) บนตัวจำลอง Intel Android ปัญหาหนึ่งคือคลาส System.Text.RegularExpressions ใน Dot42 ไม่มีฟังก์ชัน Split () ที่ฉันใช้ในการทดสอบ Xamarin ดังนั้นฉันจึงใช้คลาส Java.Util.Regex แทนและ Java.Util.Regex.Pattern.Split () ดังนั้นในสถานที่นี้โดยเฉพาะในรหัสมีความแตกต่างเล็กน้อยนี้ ไม่ควรเป็นปัญหาใหญ่ แต่ Dot42 คอมไพล์กับโค้ด Dalvik (DEX) ดังนั้นจึงร่วมมือกับ Java บน Android แบบดั้งเดิมไม่ต้องการ interop ราคาแพงจาก C # ถึง Java เช่น Xamarin

สำหรับการเปรียบเทียบฉันยังทำการทดสอบบนอุปกรณ์ ARM - ที่นี่รหัส Dot42 คือ "เท่านั้น" 2x ช้ากว่า Xamarin C # นี่คือผลลัพธ์ของฉัน:

HTC Nexus One Android 2.3.7 (ARM)

Java: เวลาทั้งหมด (5 รัน): 12187 ms, รวมการอ่านไฟล์: 13200 ms

Xamarin C #: เวลารวมทั้งหมด (5 วิ่ง): 13935 ms, รวมการอ่านไฟล์: 14465 ms

Dot42 C #: เวลารวมทั้งหมด (5 วิ่ง): 26000 ms, รวมไฟล์ที่อ่านได้: 27168 ms

Samsung Galaxy Note 2, Android 4.1.1 (ARM)

Java: เวลารวมทั้งหมด (5 วิ่ง): 6895 ms, โดยมีการอ่านไฟล์ทั้งหมด: 7275 ms

Xamarin C #: เวลารวมทั้งหมด (5 วิ่ง): 6466 ms, รวมการอ่านไฟล์: 6720 ms

Dot42 C #: เวลารวมทั้งหมด (5 วิ่ง): 11185 ms พร้อมกับอ่านไฟล์ทั้งหมด: 11843 ms

Intel emulator, Android 4.2 (x86)

Java: เวลาทั้งหมด (5 รัน): 2389 ms, รวมไฟล์ที่อ่านได้: 2770 ms

Xamarin C #: เวลารวมทั้งหมด (5 วิ่ง): 1748 ms, รวมไฟล์อ่านทั้งหมด: 1933 ms

Dot42 C #: เวลารวมทั้งหมด (5 วิ่ง): 5150 ms, รวมไฟล์ที่อ่านได้: 5459 ms

สำหรับฉันมันน่าสนใจที่จะทราบว่า Xamarin C # นั้นเร็วกว่า Java เล็กน้อยบนอุปกรณ์ ARM รุ่นใหม่และช้ากว่า Nexus One รุ่นเก่าเล็กน้อย หากใครต้องการที่จะทำการทดสอบเหล่านี้เช่นกันโปรดแจ้งให้เราทราบและฉันจะอัปเดตแหล่งข้อมูลบน GitHub มันจะน่าสนใจเป็นพิเศษหากเห็นผลลัพธ์จากอุปกรณ์ Android จริงที่มีโปรเซสเซอร์ Intel

อัพเดท 7/26/2013

เพียงอัปเดตด่วนรวบรวมใหม่โดยแอพเบนช์มาร์คมาตรฐานด้วย Xamarin.Android 4.8 และอัปเดต dot42 1.0.1.72 ที่เผยแพร่ในวันนี้ - ไม่มีการเปลี่ยนแปลงที่สำคัญจากผลลัพธ์ที่รายงานก่อนหน้านี้

อัพเดท 7/30/2556 - ผลลัพธ์ที่ดีกว่าสำหรับ dot42

ทดสอบ Dot42 อีกครั้งกับพอร์ตของ Robert (จากผู้ผลิต dot42) ของโค้ด Java ของฉันไปยัง C # ใน C # พอร์ตของฉันเสร็จสิ้นในตอนแรกสำหรับ Xamarin ฉันแทนที่คลาส Java ดั้งเดิมบางตัวเช่น ListArray ด้วย List class native เป็น C # เป็นต้น Robert ไม่ได้มีซอร์สโค้ด Dot42 ของฉันดังนั้นเขาจึงย้ายพอร์ตอีกครั้งจาก Java และใช้คลาส Java ดั้งเดิมใน สถานที่ดังกล่าวซึ่งเป็นประโยชน์ต่อ Dot42 ฉันคิดว่าเพราะมันทำงานใน Dalvik VM เช่น Java และไม่ใช่ใน Mono เช่น Xamarin ตอนนี้ผลลัพธ์ของ Dot42 นั้นดีกว่ามาก นี่คือบันทึกจากการทดสอบของฉัน:

7/30/2013 - การทดสอบ Dot42 พร้อมคลาส Java เพิ่มเติมใน Dot42 C #

Intel emulator, Android 4.2

Dot42 รหัสของ Greg โดยใช้ StringBuilder.Replace () (ใน Xamarin):
เวลารวมทั้งหมด (5 รอบ): 3646 มิลลิวินาที, รวมไฟล์ที่อ่านได้: 3830 มิลลิวินาที

Dot42, รหัสของ Greg โดยใช้ String แทนที่ () (เช่นเดียวกับใน Java และ Robert's code):
ผลรวมทั้งหมด (5 รอบการทำงาน): 3027 ms, อ่านไฟล์ได้ทั้งหมด: 3206 ms

Dot42, รหัสโรเบิร์ต:
ระยะเวลาทั้งหมด (5 รอบ): 1781 มิลลิวินาที, รวมการอ่านไฟล์: 1999 มิลลิวินาที

Xamarin:
เวลารวมทั้งหมด (5 วิ่ง): 1373 มิลลิวินาทีโดยรวมการอ่านไฟล์: 1505 มิลลิวินาที

Java:
เวลาทั้งหมด (5 รัน): 1841 มิลลิวินาที, รวมไฟล์ที่อ่านได้: 2044 มิลลิวินาที

ARM, Samsung Galaxy Note 2, ประหยัดพลังงาน, Android 4.1.1

Dot42 รหัสของ Greg โดยใช้ StringBuilder.Replace () (ใน Xamarin):
เวลาทั้งหมด (5 วิ่ง): 10875 ms, รวมไฟล์ที่อ่านทั้งหมด: 11280 ms

Dot42, รหัสของ Greg โดยใช้ String แทนที่ () (เช่นเดียวกับใน Java และ Robert's code):
ผลรวมทั้งหมด (5 รอบการทำงาน): 9710 ms, โดยมีค่าการอ่านไฟล์ทั้งหมด: 10097 ms

Dot42, รหัสโรเบิร์ต:
เวลารวมทั้งหมด (5 รอบ): 6279 มิลลิวินาที, รวมไฟล์ที่อ่านได้: 6622 มิลลิวินาที

Xamarin:
เวลารวมทั้งหมด (5 วิ่ง): 6201 ms, รวมการอ่านไฟล์: 6476 ms

Java:
เวลาทั้งหมด (5 รัน): 7141 ms, รวมไฟล์ที่อ่านได้: 7479 ms

ฉันยังคิดว่า Dot42 มีทางที่จะไปได้อีกนาน การมีคลาสเหมือน Java (เช่น ArrayList) และประสิทธิภาพที่ดีจะทำให้การย้ายรหัสจาก Java เป็น C # ง่ายขึ้นเล็กน้อย อย่างไรก็ตามนี่คือสิ่งที่ฉันไม่น่าจะทำมาก ฉันอยากจะใช้รหัส C # ที่มีอยู่ (ไลบรารี ฯลฯ ) ที่มีอยู่ซึ่งจะใช้คลาส C # ดั้งเดิม (เช่นรายการ) และจะทำงานช้าลงด้วยรหัส dot42 ปัจจุบันและดีมากกับ Xamarin

เกร็ก


5
โหมด DEBUG บน Nexus 7 4.2.2 พร้อมการปรับแต่งบางอย่างสำหรับสตริงและ xamarin alpha 9: เวลาทั้งหมด: 3907 ms โดยมีการอ่านไฟล์ทั้งหมด: 4016. "5 run" คืออะไร?
Softlion

1
"คำถามนี้มีแนวโน้มที่จะเรียกร้องการอภิปรายการหยั่งเสียงหรือการอภิปรายเพิ่มเติม" <- ดูด้านบน;)
LearnCocos2D

2
@ LearnCocos2D - ฉันแค่รายงานผลลัพธ์และตัวเลขที่เป็นรูปธรรมเช่นข้อเท็จจริง สุภาพบุรุษไม่โต้แย้งข้อเท็จจริง :)
gregko

2
นักวิทยาศาสตร์ทำ;) มันมีความแตกต่างระหว่างพฤติกรรมที่สังเกตและความจริง มีความเป็นจริงมากขึ้นและจากนั้นการบังคับใช้กับผู้ใช้ / สถานการณ์อื่น ๆ ยังคงเป็นที่น่าสงสัย นี่เป็นจุดเริ่มต้นของการวัดประสิทธิภาพพวกเขาเพียงนำเสนอข้อเท็จจริงบนพื้นผิว - จนกว่าคุณจะพบว่าผู้ขาย x ได้ปรับไดรเวอร์ให้เหมาะสมสำหรับแอพมาตรฐาน ในบันทึกที่เกี่ยวข้องพบว่าครั้งหนึ่งเคยมีการพิสูจน์แล้วว่าน้ำมีหน่วยความจำ (เช่นการทดสอบ homeopathy) ซึ่งไม่สามารถพิสูจน์ได้หลังจากพิจารณาความลำเอียงของผู้ทดสอบและตัดออกจากนั้นก็ล้มเหลวในการแสดงนัยสำคัญทางสถิติ
LearnCocos2D

3
บวกกับรุ่นถัดไป +0.1 bump theseperformance อาจมีการเปลี่ยนแปลงอย่างมีนัยสำคัญ - นั่นคือเมื่อความพยายามที่ดีทั้งหมดของคุณนำเสนอที่นี่เปลี่ยนจาก "ความจริง" เป็น "moot" อย่างไรก็ตามใครก็ตามที่มาที่นี่อาจรู้สึกว่านี่เป็นความจริงและวาดข้อสรุปที่ผิด เกณฑ์มาตรฐานอื่น ๆ : เป็นเพียงตัวแทนของช่วงเวลาที่กำหนดและรุ่นของซอฟต์แวร์ที่ใช้ ในวันถัดไปพวกเขาอาจไม่สะท้อนความเป็นจริงอีกต่อไป คุณต้องทำการทดสอบซ้ำอีกครั้ง นี่คือเหตุผลที่ผลลัพธ์ที่ได้สามารถพิจารณาแบบอัตนัยและไม่มีความหมาย
LearnCocos2D

คำตอบ:


62

ใช่แล้วเครื่องเสมือน Mono ของ Xamarin นั้นน่าประทับใจกว่า Dalvik ของ Google ที่ใช้ใน Android ฉันได้ทดสอบกับแท็บเล็ต HTC Flyer และ Acer Iconia Tab เพื่ออ้างอิงมาตรฐาน C # พอร์ตของ Android ผ่าน Mono กับ Java Dalvik ด้วยการใช้ C # ของ Android ได้ดีและทำให้ Dalvik บน Java เป็นจริง


4
@ PeterLawrey โปรดดูคำถามของฉัน ฉันตั้งใจจะโยกย้ายบางส่วนของรหัส Java ในชีวิตจริงของฉันไปที่ C # และเรียกใช้การวัดประสิทธิภาพจากนั้นโพสต์ไว้ที่นี่ - หากพวกเขาเปิดคำถามของฉันอีกครั้งนั่นคือเมื่อสัญญาณเตือนภัยปิดดังนั้นเกือบจะในทันที
gregko

1
@PeterLawrey - ตอนนี้ฉันทำการทดสอบและโพสต์ผลลัพธ์ใน StackOverflow แต่ภายในคำถามนั้นเพราะมันยังคง "ถูกล็อก" และไม่สามารถโพสต์คำตอบได้ หากทำได้โปรดเพิ่มคะแนนของคุณเพื่อเปิดคำถามอีกครั้ง ผลลัพธ์มีความน่าสนใจบน ARM Java ที่ได้รับชัยชนะบนมือรหัส Intel - C # ใน Mono นั้นเร็วกว่ามาก
gregko

9
@gregko เป็นเรื่องที่น่าสังเกตว่าคุณเห็นว่า C # ถูกเลียนแบบเร็วกว่า แต่ Java เร็วกว่าสำหรับโทรศัพท์จริง สำหรับฉันนี่คือความแตกต่างที่สำคัญ ฉันไม่ต้องกังวลเกี่ยวกับประสิทธิภาพของอีมูเลเตอร์ในความเป็นจริงฉันขอแนะนำให้คุณต้องการให้อีมูเลเตอร์ทำงานช้า / เร็วเหมือนของจริง ฉันโหวตให้เปิดใหม่อีกครั้ง
Peter Lawrey

14
ระวังเมื่อใช้นิพจน์ทั่วไปเพื่อทดสอบประสิทธิภาพ ความแตกต่างของอัลกอริทึมในการใช้ RE สามารถสร้างความแตกต่างได้อย่างมาก สิ่งที่คุณอาจทดสอบด้านบนคือคุณภาพการใช้งาน RE ไม่ใช่ Dalvik หรือ Mono VM การทดสอบที่ดีกว่าจะเป็นรหัสการแยกวิเคราะห์แบบเขียนด้วยมือซึ่งใช้อัลกอริธึมที่เหมือนกันและชัดเจนซึ่งเขียนด้วยสไตล์ที่เป็นไปตามแต่ละภาษา
คริสโตเฟอร์

4
คำตอบนี้ไม่มีค่าโดยไม่มีคำอธิบายใด ๆ เกี่ยวกับวิธีที่คุณดำเนินการทดสอบหรือผลการทดสอบเหล่านี้ ตามที่เป็นอยู่ตอนนี้: อิงตามความคิดเห็นอย่างสมบูรณ์
Rolf ツ


34

เราเพิ่งตรวจสอบโดยใช้ Xamarin สำหรับแอป เราใช้โค้ด C # ที่เราเขียนไปแล้วสำหรับแอพเวอร์ชัน Windows RT ของเรา ต้องเขียนรายละเอียดบางอย่างเฉพาะสำหรับเวอร์ชั่น Android

สิ่งที่เราค้นพบคือ I / O ใน Xamarin C # ช้ากว่า Java ประมาณ 2 เท่า แอปของเรามีการเชื่อมโยง I / O อย่างหนัก เรายังไม่ได้ค้นพบสาเหตุของสิ่งนี้ แต่ในขณะนี้เรากำลังสมมติว่ามันเกิดจากการจัดการ ในขณะที่เราพยายามอยู่ใน Mono VM เกือบตลอดเวลาเราไม่ทราบว่า Mono เข้าถึงดิสก์ได้อย่างไร

นอกจากนี้ยังบอกว่ารหัส C # ของเราใช้ SQLite.NET ( https://github.com/praeclarum/sqlite-net ) การดึงข้อมูลที่เหมือนกันโดยใช้รหัส SQLite.NET นั้นช้ากว่าการใช้ wrapper Java SQLite ของ Android เป็น 2 เท่า หลังจากดูซอร์สโค้ดมันจะผูกกับ C .dll โดยตรงดังนั้นฉันไม่รู้ว่าทำไมมันช้ากว่านี้มาก ความเป็นไปได้อย่างหนึ่งคือการที่สตริง marshaling จากเนทีฟไปที่จาวาอาจจะเร็วกว่าบน Android กว่าเนทีฟไปที่ C # นั้นอยู่บน Xamarin


1
สิ่งนี้มีโอกาสมากที่จะเกิดขึ้นกับ "การผูก" Xamerin จำเป็นต้องมีปฏิสัมพันธ์กับระบบ การเรียกใช้ระบบแต่ละครั้งเป็นค่าเริ่มต้นจะไปที่คลาส Java แต่จะต้องมอบสิทธิ์ให้กับ Mono VM ซึ่งต้องใช้เวลา สิ่งเดียวกันก็เกิดขึ้นในสิ่งที่ตรงกันข้าม ฉันได้อธิบายสิ่งนี้อีกเล็กน้อยในคำตอบของฉัน: stackoverflow.com/a/46973819/1052697
Rolf ツ

34

นี้เป็นอีกหนึ่งโพสต์บล็อกการปรับปรุงมากขึ้นผมอยากจะร่วมกับคุณ เขาเปรียบเทียบ Xamarin กับรหัสพื้นเมืองและ Cordova ทั้งใน iOS และ Android

โดยสรุปแล้ว Xamarin ทำงานได้ดีกว่ารหัสท้องถิ่น เขาทดสอบขนาดแอพเวลาโหลดโหลดรายการจากบริการ Azure และการคำนวณจำนวนเฉพาะ

สนุก!

แก้ไข: ฉันอัปเดตลิงก์ที่ใช้งานไม่ได้และฉันสังเกตเห็นว่ามีส่วนที่ 2


11

นี่คือข้อมูลบางอย่างที่ฉันพบในการทดสอบอีกแบบระหว่าง Native, Xamarin และ Xamarin.Forms solutions (การทดสอบรวมถึงการแสดง iOS) บนอุปกรณ์สองเครื่องต่อไปนี้:

Samsung Galaxy A7 : รุ่น Android OS: 6.0 หน่วยประมวลผลกลาง: Octa-core 1.9 GHz Cortex-A53 RAM: 3GB ความละเอียดการแสดงผล: 1920 × 1080

iPhone 6s : iOS เวอร์ชั่น: 10.3.3 หน่วยประมวลผลกลาง: Dual-Core 1.84 GHz Twister RAM: 2 GB ความละเอียดการแสดงผล: 1334 × 750

ทำการเปรียบเทียบกับคุณสมบัติทั่วไปบางอย่างโดยแต่ละแอปพลิเคชั่นมี:

- Basic Hello World
- REST API
- JSON Serialization/Deserialization
- Photo Loading
- SQL Database Insert and Get All

การทดสอบแต่ละครั้งจะถูกทำซ้ำหลายครั้งกราฟแสดงผลเฉลี่ย


สวัสดีชาวโลก

การเปรียบเทียบประสิทธิภาพ Hellow World ขั้นพื้นฐาน


ส่วนที่เหลือ API

ชุดการทดสอบมุ่งวัดเวลาที่แอพส่งคำขอผ่าน REST API และรับการตอบกลับโดยไม่ต้องประมวลผลข้อมูลเพิ่มเติมโดยใช้ OpenWeatherMap API

เปรียบเทียบประสิทธิภาพ API ส่วนที่เหลือ


การ ทดสอบการปฏิบัติงานของ JSONสร้างขึ้นโดยใช้เฟรมเวิร์ก Newtonsoft Json.net เพื่อทำให้เป็นอันดับและทำให้เป็นวัตถุวัตถุ JSON ในแอป Xamarin ทั้งหมด การทำให้เป็นอนุกรมและการดีซีเรียลไลเซชั่นของ Android พื้นเมืองทดสอบโดยใช้สองไลบรารี Java: Jackson และ GSON

มีการวิ่งสองครั้งโดยเริ่มจากศูนย์และที่สองที่มีข้อมูลแคชและการดำเนินการ

วิ่งครั้งแรก:

การทำให้เป็นอันดับ JSON ทำงานครั้งแรก

การดีซีเรียลไลซ์เซชั่น JSON ทำงานครั้งแรก

(Native iOS JSON Operations กำลังทดสอบ btw นี้และ Xamarin เชื่อมต่อในวินาที)

การทำให้เป็นอันดับ JSON ที่สองทำงาน

JSON Deserialization รันครั้งที่สอง


การถ่ายภาพ

การโหลดครั้งแรกกับภาพที่มีความละเอียดต่างกันสามแบบ:

Resolution  858×569, Size  868Kb
Resolution  2575×1709, Size  8Mb
Resolution  4291×2848, Size  28.9Mb

ภาพแรกโหลด Android

Image โหลด iOS ครั้งแรก

ดูเหมือนว่ามีบางสิ่งที่ไม่แน่ใจเกี่ยวกับ Xamarin ผลที่ได้จากการทดสอบนี้จึงไม่รวมอยู่ในกราฟ


การดำเนินงาน SQLite

ผ่านการทดสอบสองการทดสอบ:

BulkInsert: Loading rows of data into a database table.
GetAll: Retrieving all data from the database.

ด้วยฐานข้อมูลที่มี 10,000 ระเบียน การดำเนินการทั้งหมดถูกประมวลผลภายในบนอุปกรณ์

การแสดงของ SQLite Android

การแสดงของ SQLite iOS


Xamarin Native (Xamarin.iOS / Xamarin.Android) แสดงให้เห็นว่ามันเป็นทางเลือกที่ดีสำหรับรหัสพื้นเมืองในขณะที่ Xamarin.Forms ดูเหมือนจะช้าในหลายกรณี แต่มันก็เป็นทางออกที่ดีในการพัฒนาแอพพลิเคชั่นที่ง่ายจริงๆอย่างรวดเร็ว

การทดสอบที่สมบูรณ์มาจากแหล่งข้อมูลนี้:

https://www.altexsoft.com/blog/engineering/performance-comparison-xamarin-forms-xamarin-ios-xamarin-android-vs-android-and-ios-native-applications/

ขอบคุณที่ให้คำอธิบายแก่ฉันเพื่อปรับปรุงคำตอบของฉันหวังว่านี่จะช่วยได้เล็กน้อย :)


7

ประสิทธิภาพ

ประสิทธิภาพเป็นคำที่คลุมเครือหากคุณไม่ได้กำหนดสิ่งที่คุณหมายถึงโดยการปฏิบัติถ้ามันเป็นประสิทธิภาพการคำนวณธรรมดา Xamarin สามารถเร็วกว่า Java ขึ้นอยู่กับลักษณะของการคำนวณ

Android nativly มาพร้อมกับฟอร์มหลายอย่างเพื่อรันโค้ดใน:

  • RenderScript (CPU และ GPU)
  • Java (SDK)
  • C ++ (NDK)
  • OpenGL (GPU)

เห็นได้ชัดว่าเมื่อรันโค้ดมากขึ้นวิธีการแก้ปัญหาก็จะเร็วขึ้น ภาษาที่ใช้เวลาทำงานจะไม่ชนะภาษาที่ทำงานบน CPU โดยตรง

แต่ในทางกลับกันถ้าคุณต้องการวัดประสิทธิภาพการใช้งานในชีวิตจริง Java นั้นเป็นไปได้เร็วกว่า Xamarin

ซามารินและทำไมมันถึงช้าลง

เมื่อเปรียบเทียบ Xamarin กับแอปพลิเคชัน Java แบบเก่าธรรมดาประสิทธิภาพการทำงานของ Xamarin นั้นช้ากว่ามาก

ในโลกแห่งความเป็นจริงตัวอย่างแอปพลิเคชัน Xamarin มีแนวโน้มที่จะช้ากว่าแอปพลิเคชัน Java เนื่องจากการโทร Android / Java (ระบบ) จำนวนมากต้องได้รับการมอบหมายให้เข้าและออกจากรันไทม์ Xamarin โดยใช้การเชื่อมที่เรียกว่า

มีการผูกประเภทต่าง ๆ ที่สำคัญที่ต้องทราบ:

  • JNI (Java Native Interface):การเชื่อมโยงที่ใช้ในแอพพลิเคชั่น Android จำนวนมากเพื่อเชื่อมต่อระหว่างโค้ด Java (SDK) และโค้ด C ++ ดั้งเดิม (NDK)
  • MCW (Managed Callable Wrappers):การเชื่อมโยงที่มีอยู่ใน Xamarin ไปยังส่วนต่อประสานจากรหัส C # ที่ได้รับการจัดการไปยังรหัส Java (Android รันไทม์)
  • ACW (Android Callable Wrappers):การเชื่อมโยงที่มีอยู่ใน Xamarin ไปยังส่วนต่อประสานจากรหัส Java (เวลาทำงาน Android) ไปยังรหัส C # ที่ได้รับการจัดการ

เพิ่มเติมเกี่ยวกับ MCW และ ACW ที่นี่: https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_1_-_understanding_the_xamarin_mobile_platform/

การผูกข้อมูลในแง่ของประสิทธิภาพมีราคาแพงมาก การเรียกใช้เมธอด C ++ จาก Java จะเพิ่มค่าใช้จ่ายจำนวนมากในเวลาโทรการเรียกเมธอด C ++ จากภายใน C ++ นั้นเร็วกว่ามากหลายเท่า

มีคนทำการทดสอบประสิทธิภาพเพื่อคำนวณจำนวนการดำเนินการของ Java โดยเฉลี่ยต่อค่าใช้จ่ายในการโทร JNI: ค่าใช้จ่ายเชิงปริมาณในการโทร JNI คืออะไร

แต่การโทร JNI นั้นมีค่าใช้จ่ายสูงนั้นเป็นการโทรเข้าและออกจาก MCW และ ACW แอปพลิเคชัน Xamarin ในโลกแห่งความจริงทำให้การโทรจำนวนมากโดยใช้การเชื่อมโยงและเนื่องจากการใช้งานจริงของแอปพลิเคชัน Xamarin อาจทำให้ (และโดยทั่วไปจะ) ช้ากว่าแอปพลิเคชัน Java แบบเก่าธรรมดา อย่างไรก็ตามขึ้นอยู่กับวิธีการออกแบบแอปพลิเคชัน Xamarin มันมีโอกาสมากที่ผู้ใช้จะไม่สังเกตเห็นความแตกต่าง

TLDR / บทสรุป: Xamarin จำเป็นต้องใช้การเรียงลำดับอัลซึ่งจะเสียเวลา

นอกจากการเชื่อมโยงแล้วยังมีปัจจัยอื่น ๆ อีกมากมายที่เกี่ยวข้องเมื่อพูดถึงประสิทธิภาพการทำงานจริงเช่นขนาดของไบนารีโหลดแอปในหน่วยความจำการทำงานของ I / O และอื่น ๆ อีกมากมาย บล็อกโพสต์ที่ตรวจสอบบางสิ่งเหล่านี้สามารถพบได้ที่นี่: https://magenic.com/thinking/mobile-development-platform-performance-part-2-native-cordova-classic-xamarin-xamarin-forms


2

เป็นการทดสอบที่ค่อนข้างเก่า แต่อาจมีความเกี่ยวข้อง: https://github.com/EgorBo/Xamarin.Android-vs-Java

การทดสอบทางคณิตศาสตร์

ป้อนคำอธิบายรูปภาพที่นี่

คอลเลกชัน generics ประเภทค่าที่กำหนดเอง

ป้อนคำอธิบายรูปภาพที่นี่

ทำงานกับสตริง

ป้อนคำอธิบายรูปภาพที่นี่

UPD:ข้อมูลใหม่ด้วย Google Pixel 2 (ขอบคุณyousha-aleayoub )

การทดสอบ Pixel 2


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.