เหตุใดจึงถูก“ ลบ Enums ที่คุณต้องการ Ints” จากเคล็ดลับประสิทธิภาพการทำงานของ Android


175

ส่วน "Enums หลีกเลี่ยงการที่คุณจะ Ints ต้องการ" ถูกลบออกจากอย่างเป็นทางการเอกสารนักพัฒนา (ดูเหตุใด Android จึงไม่ใช้ enums มากกว่านี้สำหรับเนื้อหาส่วนเก่า)

ทำไม? มีการเปลี่ยนแปลงใน Android VM ที่ทำให้ทิปล้าสมัยหรือไม่?


2
สำหรับการอ้างอิงนี่คือdecompiled bytecode สำหรับไม้พุ่มเช่น: https://gist.github.com/847418
จอชลี

15
ตั้งแต่เดือนมีนาคม 2014 หน้าต่อไปนี้ยังคงมีคำแนะนำในการใช้ enums: developer.android.com/training/articles/memory.html#Overhead
Tahir Akhtar

2
อีกหนึ่งปีต่อมาในขณะที่ @TahirAkhtar กล่าวว่าการฝึกอบรม Android อย่างเป็นทางการยังคงกล่าวว่า "คุณควรหลีกเลี่ยงการใช้ enums บน Android อย่างเคร่งครัด"
LarsH

1
ที่น่าสนใจที่จะทราบคำแนะนำเพื่อหลีกเลี่ยงการ enum อยู่ในบทความปี 2558 นี้จากผู้พัฒนา Android ที่เป็นผู้นำ: medium.com/google-developers/ ...... นอกจากนี้: "โปรดทราบว่าการใช้คำอธิบายประกอบ @IntDef ซึ่งรองรับโดย Android Studio และ Gradle 1.3+ จะให้ความปลอดภัยประเภทการสร้างรหัสของคุณในเวลา (เมื่อเปิดใช้งานข้อผิดพลาดผ้าสำลี) ในขณะที่รักษาขนาดและประโยชน์ด้านประสิทธิภาพของการใช้ตัวแปร int "
tonylo

4
ตั้งแต่เมษายน 2018 หน้าต่อไปนี้ไม่มีคำแนะนำในการใช้ enums อีกต่อไป developer.android.com/topic/performance/memory#Overhead
Robin Davies

คำตอบ:


157

เอกสารต้นฉบับฉบับนั้นเป็นอคติอย่างมาก มีการเขียนใหม่เพื่อให้มีข้อมูลสำรองตามเกณฑ์มาตรฐานจริงเท่านั้นและได้รับการอัปเดตเมื่อมีการอัปเดต VM คุณสามารถหามาตรฐานต่างๆ - รวมทั้งบางส่วนของมาตรฐานที่เราใช้เพื่อเพิ่มประสิทธิภาพห้องสมุดหลัก - ที่http://code.google.com/p/dalvik/


35
มันจะช่วยถ้าคุณแสดงข้อมูลประจำตัวของคุณในโปรไฟล์ SO ของคุณ ฉันต้องขุดบ้างรอบ ๆ แต่ตอนนี้ฉันเห็นว่าคุณดูเหมือนจะทำงานกับทีม VM ฉันจะยอมรับคำตอบของคุณเป็นคำตอบอย่างเป็นทางการ :)
Thierry-Dimitri Roy

25
แน่นอนว่าการเพิ่มคลาส enum หมายความว่าแอปของคุณมีคลาสพิเศษดังนั้นจึงไม่ฟรีแต่เราต้องสมมติว่านักพัฒนาเพิ่มเพียงแค่จำนวนเงินที่มีประโยชน์ การใช้งานที่แย่มาก ๆ อย่างเดียวที่ฉันเคยเห็นของ enums อยู่ในรหัสความสามัคคีที่พวกเขาต้องการ ints (สำหรับ bitmasks และชอบ) และ "enum" ไม่ใช่ enum ในแง่ที่สมเหตุสมผล หากคุณพบว่าตัวเองกำลังเรียก "ordinal ()" อยู่มากนั่นอาจเป็นกลิ่นเหม็นซึ่งหมายความว่าคุณไม่ต้องการ enum แต่นั่นไม่ใช่เคล็ดลับเฉพาะสำหรับ Android และเป็นข้อผิดพลาดในการออกแบบที่หายากจริงๆ
Elliott Hughes

17
คือเอกสารนี้ออกจากวันได้เป็นอย่างดี @ Thierry-DimitriRoy? โดยเฉพาะคุณควรหลีกเลี่ยงการใช้ enums บน Android อย่างเคร่งครัด
Jacob Tabak

3
FWIW, Proguard จะแปลง enums เป็น intsโดยค่าเริ่มต้น
Nacho Coloma

11
ลิงค์ที่คุณให้นั้นตายไปแล้ว
เทอร์รี่

26

เดา:

  • ซีพียู Gigahertz อย่าง Hummingbird และ Snapdragon นั้นเป็นเรื่องธรรมดาและข้อกำหนดขนาดเล็กของหน่วยความจำขนาดเล็กซึ่ง แต่เดิม จำกัด Dalvik VM นั้นไม่เป็นความจริงอีกต่อไป
  • อุปกรณ์จัดส่งทุกชิ้นใช้ JIT (ใหม่ถึง 2.2) ตัวกำหนดค่าเริ่มต้นของคลาส enum จะทำงานได้เร็วขึ้นค่าอาจถูกใช้เป็นค่าคงที่ของเวลา JIT และ JIT อาจได้รับการสนับสนุนพิเศษสำหรับการเพิ่มความคล่องตัวของคลาส enum
  • รหัสซึ่งเป็นจริงๆใช้ประสิทธิภาพการทำงานที่สำคัญ NDK ซึ่งยังคงใหม่และข้าวกล้องเมื่อ Android 1.5 ได้รับการปล่อยตัว NDK in 2.3 รองรับกิจกรรมเนทีฟซึ่งช่วยให้เกมที่ไม่มีการจัดการใกล้เคียงเต็ม

ดังนั้นสำหรับความต้องการที่ค่อนข้างธรรมดาของแอพ GUI ประโยชน์จากการพัฒนาของ enums นั้นมีมากกว่าค่าใช้จ่ายพิเศษ


23

Elliott Hughes เสนอรายละเอียดเพิ่มเติมเกี่ยวกับการเขียนเอกสารใหม่ในบล็อกของเขา: http://elliotth.blogspot.com/2010/09/java-benchmarks.html

โพสต์ในช่วงครึ่งหลังของโพสต์อธิบายว่าทุกการเรียกร้องในเอกสารประสิทธิภาพได้รับการสำรองด้วยมาตรฐาน เห็นได้ชัดว่าเอกสารก่อนหน้านี้มีการอ้างสิทธิ์ที่ยังไม่ผ่านการตรวจสอบเช่น "หลีกเลี่ยงการใช้เงินเนื่องจากมีราคาแพงเกินไป"


แค่ต้องการเสริมคำตอบที่ยอมรับของ Elliott ด้วยลิงก์นี้
jkooker

12

คำตอบในปี 2011 จาก Elliot Hugues กล่าวว่าเหตุผลดั้งเดิมที่จะหลีกเลี่ยง enum นั้นคือเหตุผลด้านประสิทธิภาพ ... เช่นเดียวกับ "ประสิทธิภาพการประมวลผล" เนื่องจากเหตุผลนี้ไม่ได้รับการสนับสนุนโดยข้อเท็จจริงจึงถูกลบออกจากเอกสารราชการ

ถูกเพิ่มในภายหลังเนื่องจาก enums เพิ่มข้อมูลในหน่วยความจำมากกว่าการใช้จำนวนเต็ม


2
นอกจากนี้ Google ยังมีIntDefคำอธิบายประกอบซึ่งอนุญาตให้ใช้ค่าคงที่ int อย่างปลอดภัยพร้อมกับข้อผิดพลาดและการเตือนของ Android Studio blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.

9

TLDR: Dalvik ไม่ดีกับการจัดสรรหน่วยความจำและใช้หน่วยความจำมากกว่าEnum intAndroid Lollipop แทนที่ Dalvik ด้วย ART ซึ่งไม่ได้รับผลกระทบจากข้อ จำกัด เดียวกัน ดังนั้นคำแนะนำนี้จึงไม่เกี่ยวข้องอีกต่อไป

คำตอบที่ยาว:

ว้าว! 8 ปี 5 คำตอบและความคิดเห็นมากมายต่อมาเหตุผลที่แท้จริงยังไม่ได้รับการแก้ไข

ในยุคก่อนอมยิ้ม Android Dalvik เป็นกระบวนการที่ VM ใช้ เนื่องจากมีหน่วยความจำขนาดเล็กสำหรับแอปพลิเคชันที่ใช้ในช่วงเวลานั้น Dalvik จึงมีข้อ จำกัด ด้านหน่วยความจำมากมาย สำหรับการจัดสรรหน่วยความจำ Dalvik ต้องเดินไปที่กองและหาพื้นที่ กองก็จะได้รับการแยกส่วนเมื่อเวลาผ่านไป Dalvik ไม่สามารถจัดเรียงข้อมูลได้ดังนั้นจึงจะจัดสรรเมื่อเวลาผ่านไปและในที่สุดพื้นที่ก็จะหมด

หลีกเลี่ยง Enums ที่คุณต้องการเพียง Ints

มาจาก Dalvik วันเพราะมีEnumขนาดใหญ่กว่าintและการจัดสรรหน่วยความจำมีราคาแพงมาก

กรอไปข้างหน้าวันนี้ Dalvik ถูกแทนที่ด้วย ART ART ออกมาใน KitKat และเป็นค่าเริ่มต้นตั้งแต่ Lollipop

ART ถูกสร้างขึ้นจากพื้นฐานไม่ได้เพิ่มประสิทธิภาพสำหรับหน่วยความจำ แต่เพื่อเพิ่มประสิทธิภาพการทำงาน นอกจากนี้ยังเหมาะสำหรับการจัดสรรและการรวบรวม เหตุผลก็คือมีหน่วยความจำตั้งไว้สำหรับวัตถุขนาดใหญ่ แทนที่จะใส่ทุกอย่างไว้ในกองเดียวกันแล้วต้องหาที่ว่างสำหรับวัตถุขนาดใหญ่ท่ามกลางวัตถุชิ้นเล็ก ๆ ART วางวัตถุขนาดใหญ่และบิตแมปทั้งหมดในกองแยกต่างหาก จากนั้นวัตถุเล็ก ๆ จะไปอยู่ในกองแยก นอกจากนี้ยังสามารถจัดระเบียบ

หลังจาก ART ถ้าคุณใช้EnumAndroid ไม่สนใจและนี่คือสาเหตุที่คำแนะนำหายไปในขณะนี้

สิ่งนี้มาจาก Chet Haase ที่ Google ฉันแนะนำให้หา Google I / O ของเขาคุยและดูวิดีโอทั้งหมด มันมีข้อมูลที่เป็นประโยชน์มากมายและข้อมูลเชิงลึกเกี่ยวกับ Android


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