แม้ว่าคำตอบที่เสนอให้ใช้ ArrayList นั้นสมเหตุสมผลในสถานการณ์ส่วนใหญ่ แต่คำถามที่แท้จริงของประสิทธิภาพที่สัมพันธ์กันนั้นยังไม่ได้รับคำตอบจริงๆ
มีบางสิ่งที่คุณสามารถทำกับอาร์เรย์:
- สร้างมัน
- ตั้งค่ารายการ
- รับรายการ
- โคลน / คัดลอก
บทสรุปทั่วไป
แม้ว่าการรับและการตั้งค่าจะค่อนข้างช้ากว่าใน ArrayList (การตอบสนองที่ 1 และ 3 nanosecond ต่อการโทรบนเครื่องของฉัน) มีค่าใช้จ่ายน้อยมากในการใช้ ArrayList กับอาเรย์สำหรับการใช้ที่ไม่ต้องใช้ความรุนแรงใด ๆ อย่างไรก็ตามมีบางสิ่งที่ต้องจำไว้:
- การปรับขนาดการดำเนินการในรายการ (เมื่อโทร
list.add(...)
) มีค่าใช้จ่ายสูงและควรพยายามตั้งค่าความจุเริ่มต้นในระดับที่เพียงพอเมื่อเป็นไปได้ (โปรดทราบว่าปัญหาเดียวกันนี้เกิดขึ้นเมื่อใช้อาร์เรย์)
- เมื่อต้องรับมือกับลำดับต้น ๆ อาร์เรย์จะเร็วขึ้นอย่างมากเนื่องจากจะช่วยให้ผู้ใช้สามารถหลีกเลี่ยงการแปลงมวย / ไม่แปลงจำนวนมาก
- แอปพลิเคชันที่รับ / ตั้งค่าใน ArrayList เท่านั้น (ไม่ธรรมดามาก!) จะเห็นประสิทธิภาพที่เพิ่มขึ้นมากกว่า 25% โดยการสลับไปที่อาร์เรย์
รายละเอียดผลลัพธ์
นี่คือผลลัพธ์ที่ฉันวัดสำหรับการดำเนินการทั้งสามนี้โดยใช้ไลบรารีการเปรียบเทียบ jmh (คูณเป็นนาโนวินาที) ด้วย JDK 7 บนเครื่องเดสก์ท็อปมาตรฐาน x86 โปรดทราบว่า ArrayList จะไม่ถูกปรับขนาดในการทดสอบเพื่อให้แน่ใจว่าผลลัพธ์จะได้รับการเปรียบเทียบ รหัสเกณฑ์มาตรฐานอยู่ที่นี่
การสร้าง ArrayList / ArrayList
ฉันทดสอบ 4 ครั้งรันคำสั่งต่อไปนี้:
- createArray1:
Integer[] array = new Integer[1];
- createList1:
List<Integer> list = new ArrayList<> (1);
- createArray10000:
Integer[] array = new Integer[10000];
- createList10000:
List<Integer> list = new ArrayList<> (10000);
ผลลัพธ์ (เป็นนาโนวินาทีต่อการโทร, มั่นใจ 95%):
a.p.g.a.ArrayVsList.CreateArray1 [10.933, 11.097]
a.p.g.a.ArrayVsList.CreateList1 [10.799, 11.046]
a.p.g.a.ArrayVsList.CreateArray10000 [394.899, 404.034]
a.p.g.a.ArrayVsList.CreateList10000 [396.706, 401.266]
สรุป: ไม่มีความแตกต่างที่เห็นได้ชัด
รับการดำเนินงาน
ฉันทดสอบ 2 ครั้งรันคำสั่งต่อไปนี้:
- getList:
return list.get(0);
- getArray:
return array[0];
ผลลัพธ์ (เป็นนาโนวินาทีต่อการโทร, มั่นใจ 95%):
a.p.g.a.ArrayVsList.getArray [2.958, 2.984]
a.p.g.a.ArrayVsList.getList [3.841, 3.874]
บทสรุป: การได้รับจากอาเรย์นั้นเร็วกว่าการรับ ArrayList ประมาณ 25%ถึงแม้ว่าความแตกต่างจะอยู่ในคำสั่งของหนึ่งนาโนวินาทีเท่านั้น
ชุดปฏิบัติการ
ฉันทดสอบ 2 ครั้งรันคำสั่งต่อไปนี้:
- ลิสท์:
list.set(0, value);
- setArray:
array[0] = value;
ผลลัพธ์ (เป็นนาโนวินาทีต่อการโทร):
a.p.g.a.ArrayVsList.setArray [4.201, 4.236]
a.p.g.a.ArrayVsList.setList [6.783, 6.877]
บทสรุป: การดำเนินการที่กำหนดไว้ในอาร์เรย์นั้นเร็วกว่ารายการประมาณ 40%แต่สำหรับการดำเนินการแต่ละชุดใช้เวลาไม่กี่นาโนวินาทีดังนั้นความแตกต่างในการเข้าถึง 1 วินาทีหนึ่งจะต้องตั้งค่ารายการในรายการ / อาร์เรย์หลายร้อย ของล้านครั้ง!
โคลน / คัดลอก
ArrayList ของผู้ได้รับมอบหมายสำเนาคอนสตรัคไปArrays.copyOf
เพื่อประสิทธิภาพเป็นเหมือนสำเนาอาร์เรย์ (คัดลอกอาร์เรย์ผ่านclone
,Arrays.copyOf
หรือSystem.arrayCopy
ทำให้ประสิทธิภาพการทำงานที่ชาญฉลาดไม่แตกต่างกันวัสดุ )