ความแตกต่างระหว่าง Array และ List ใน scala


142

ในกรณีใดฉันควรใช้ Array (Buffer) และ List (Buffer) ความแตกต่างเพียงอย่างเดียวที่ฉันรู้คืออาร์เรย์นั้นไม่แปรปรวนและรายการต่าง ๆ แปรปรวน แต่สิ่งที่เกี่ยวกับประสิทธิภาพและลักษณะอื่น ๆ ?

คำตอบ:


155

โครงสร้างที่ไม่เปลี่ยนรูป

สกาล่าListเป็นโครงสร้างข้อมูลที่ไม่เปลี่ยนรูป recursive ซึ่งเป็นเช่นโครงสร้างพื้นฐานในสกาล่าที่คุณควร (อาจ) จะใช้มันมากขึ้นกว่าArray(ซึ่งเป็นจริงแน่นอน - The อนาล็อกไม่เปลี่ยนรูปของArrayเป็นIndexedSeq)

ถ้าคุณมาจากพื้นหลัง Java แล้วขนานที่เห็นได้ชัดคือเมื่อใช้มากกว่าLinkedList ArrayListโดยทั่วไปจะใช้สำหรับรายการที่เคยผ่านการสำรวจก่อนเท่านั้น(และไม่ทราบขนาดล่วงหน้า) ในขณะที่รายการหลังควรใช้รายการที่มีขนาดที่รู้จัก (หรือขนาดสูงสุด) หรือการเข้าถึงแบบสุ่มอย่างรวดเร็วเป็นสิ่งสำคัญ

โครงสร้างที่ไม่แน่นอน

ListBufferให้การแปลงเวลาคงListที่ซึ่งเป็นเหตุผลเดียวที่จะใช้ListBufferหากจำเป็นต้องมีการแปลงในภายหลัง

Scala Arrayควรถูกนำไปใช้กับ JVM โดยอาร์เรย์ Java และด้วยเหตุนี้Array[Int]อาจมีประสิทธิภาพมากกว่า (ในฐานะint[]) มากกว่า a List[Int](ซึ่งจะทำกล่องเนื้อหาของมันยกเว้นว่าคุณกำลังใช้ Scala รุ่นล่าสุดซึ่งมี@specializedคุณสมบัติใหม่) .

อย่างไรก็ตามฉันคิดว่าการใช้Arrays ใน Scala ควรถูกเก็บไว้ให้น้อยที่สุดเพราะรู้สึกว่าคุณจำเป็นต้องรู้ว่าเกิดอะไรขึ้นภายใต้ประทุนเพื่อตัดสินใจว่าอาเรย์ของคุณจะได้รับการสนับสนุนตามประเภทดั้งเดิมที่ต้องการหรืออาจ ชนิดบรรจุกล่อง


ยังเห็นstackoverflow.com/questions/3213368/ …และstackoverflow.com/questions/2481149/… คำจำกัดความของ "เท่ากับ" สำหรับ Array คือพวกเขาอ้างถึงอาร์เรย์เดียวกัน
oluies

130

นอกจากคำตอบที่โพสต์แล้วนี่คือรายละเอียดบางอย่าง

ในขณะที่Array[A]เป็นอักษรอาร์เรย์ Java ที่List[A]เป็นโครงสร้างข้อมูลที่ไม่เปลี่ยนรูปที่เป็นทั้งNil(รายการว่างเปล่า) (A, List[A])หรือประกอบด้วยคู่

ความแตกต่างด้านประสิทธิภาพ

                          Array  List
Access the ith element    θ(1)   θ(i)
Delete the ith element    θ(n)   θ(i)
Insert an element at i    θ(n)   θ(i)
Reverse                   θ(n)   θ(n)
Concatenate (length m,n)  θ(n+m) θ(n)
Count the elements        θ(1)   θ(n)

ความแตกต่างของหน่วยความจำ

                          Array  List
Get the first i elements  θ(i)   θ(i)
Drop the first i elements θ(n-i) θ(1)
Insert an element at i    θ(n)   θ(i)
Reverse                   θ(n)   θ(n)
Concatenate (length m,n)  θ(n+m) θ(n)

ดังนั้นถ้าคุณต้องการเข้าถึงแบบสุ่มอย่างรวดเร็วจำเป็นต้องนับองค์ประกอบหรือด้วยเหตุผลบางอย่างที่คุณจำเป็นต้องมีการปรับปรุงการทำลายล้างที่เป็นดีกว่าListArray


Os เหล่านี้ต้องพิจารณาเวลาในการคัดลอกรายการหรือไม่ ฉันคิดว่าคุณกำลังทำแบบทดสอบนี้เช่น: list = list.drop(i). หรือว่ามีเวทมนตร์บางอย่างอยู่ด้านหลังฝากระโปรง?

2
สิ่งนี้จะรวมถึงการคัดลอกรายการและอาร์เรย์เมื่อจำเป็น โปรดทราบว่าสิ่งต่าง ๆdropไม่จำเป็นต้องคัดลอกส่วนของรายการที่ไม่ได้ลดลง เช่น(x::xs).drop(1)เป็นสิ่งxsไม่ได้เป็น "คัดลอก" xsของ
Apocalisp

6
Asymptotics เหล่านี้ไม่มีส่วนเกี่ยวข้องกับ Scala แต่อย่างใด โครงสร้างข้อมูลที่เหมือนกันใน C จะรวดเร็วเท่ากับปัจจัยคงที่
Apocalisp

1
@Apocalisp คุณมีข้อมูลอ้างอิงหรือไม่ภายใต้เงื่อนไขใดที่คุณพิจารณาข้อมูลนี้
Phil

1
@Phil เหล่านี้คืออาการเชิงอาการไม่ใช่การวัด พวกเขาจะถือเป็นจริงภายใต้เงื่อนไขทั้งหมด
Apocalisp

18

Array นั้นไม่แน่นอนซึ่งหมายความว่าคุณสามารถเปลี่ยนค่าของแต่ละดัชนีในขณะที่ List (โดยค่าเริ่มต้น) นั้นไม่เปลี่ยนรูปหมายความว่ารายการใหม่จะถูกสร้างขึ้นทุกครั้งที่คุณทำการปรับเปลี่ยน ในกรณีส่วนใหญ่มันเป็นอีกสไตล์ "การทำงาน" เพื่อทำงานร่วมกับประเภทข้อมูลไม่เปลี่ยนรูปและคุณอาจจะลองและใช้รายการที่มีโครงสร้างเหมือนyield, foreach, matchและอื่น ๆ

สำหรับคุณลักษณะด้านประสิทธิภาพอาร์เรย์จะเร็วขึ้นด้วยการเข้าถึงองค์ประกอบแบบสุ่มในขณะที่รายการจะเร็วขึ้นเมื่อเตรียม (เพิ่ม) องค์ประกอบใหม่ การพูดซ้ำพวกมันเปรียบได้


@leonm - apols ฉันคิดว่า OP กำลังถามเฉพาะเกี่ยวกับ * วิชาบัฟเฟอร์ฉันรู้ว่าพวกเขายังถามเกี่ยวกับคน "ปกติ" ด้วย!
oxbow_lakes

2
โดยปกติแล้วการผนวก ArrayBuffer เร็วกว่าการผนวกเข้ากับ List (หรือเพิ่มองค์ประกอบใน ListBuffer) เนื่องจากรายการต้องการการสร้างวัตถุ wrapper ในขณะที่ ArrayBuffer เพียงต้องการคัดลอกวัตถุ (โดยเฉลี่ยประมาณสองครั้ง) ไปยังอาร์เรย์ใหม่ . โดยทั่วไปแล้วสำเนาสองชุดจะเร็วกว่าการสร้างวัตถุหนึ่งรายการดังนั้น ArrayBuffer จะผนวกรายการ beats List prepend
Rex Kerr

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