Mengapa koleksi java yang berbeda memiliki kapasitas default yang berbeda?

11

Melihat berbagai konstruktor koleksi pertanyaan muncul di benak. Mengapa ArrayList () membuat daftar kosong dengan kapasitas awal sepuluh dan ArrayDeque () membuat deque array kosong dengan kapasitas awal yang cukup untuk menampung 16 elemen.

Badman Gray Tua
sumber
Saya tidak baru yang memiliki batas kapasitas. Saya hanya cukup menambahkan elemen baru dengan add (). Selalu berhasil.
Tulains Córdova
1
Saya pikir dia berbicara tentang ukuran array awal dari array di dalam implementasi ArrayList. Seperti namanya, ArrayList hanyalah array biasa-lama di bawah selimut, dan itu menciptakan array yang lebih besar secara otomatis ketika Anda mencoba menambahkan lebih banyak elemen daripada ukuran array saat ini.
dsw88
1
Saya pikir StringBuilder adalah yang lain yang memiliki kapasitas default, apakah 10 atau 16?
Ingo
@Ingo Menarik. Saya bahkan tidak menyadari hal-hal di luar koleksi yang berantakan dengan kapasitas, tetapi saya rasa itu masuk akal. Pada saat itu tidak ada tag untuk kapasitas jadi saya yang tidak memicu minat banyak kegunaan lain.
Old Badman Grey

Jawaban:

17

Jawaban singkat

Karena kapasitas ArrayDeque harus menjadi kekuatan dua, dan 16 adalah kekuatan terkecil dari dua yang setidaknya 10.


ArrayDeque perlu menggunakan banyak operasi% di mana-mana untuk membungkus array linier yang berpura-pura bundar.

a % bdapat dinyatakan seolah- a & (b - 1) olah b adalah kekuatan dua. Bitwise AND secara besar-besaran lebih cepat sehingga kapasitas ArrayDeque dibatasi menjadi kekuatan dua. Semua% operasi dilakukan dengan bitmasking, bukan% aktual dalam implementasi.

Ini juga mengapa HashMap yang lebih baru tidak menggunakan ukuran tabel bilangan prima tetapi kekuatan dua , lagi karena operasi% perlu dilakukan begitu sering dan bitwise dan itu jauh lebih cepat.

Jadi jika garis dasarnya adalah 10, maka struktur yang memiliki kekuatan dua batasan harus menggunakan 16 karena itu kekuatan terkecil dari dua yang setidaknya 10.

Esailija
sumber
3

Jangan mengecualikan kemungkinan bahwa tidak ada alasan khusus.

Bisa jadi kedua koleksi ini telah ditulis oleh tim yang berbeda. Keduanya memilih angka kecil sebagai kapasitas default, tetapi tim pertama berpikir secara desimal dan memilih 10, sedangkan tim kedua berpikir biner dan memilih 16.

rem
sumber
1

Jawaban @ Esailija baik untuk kasus khusus ini.

Lebih umum lagi, ini merupakan trade-off yang tergantung pada banyak faktor. Saya akan memberikan beberapa contoh:

  • Bagaimana struktur data biasanya digunakan ? Struktur data yang digunakan sebagai buffer data biasanya akan memilih kapasitas yang jauh lebih tinggi daripada struktur data yang digunakan untuk tupel kecil, misalnya.
  • Apa ukuran data standar yang cocok dengan garis cache pada platform CPU target Anda? Ini dapat membuat perbedaan besar untuk kinerja jika standarnya sesuai dengan garis cache. Pilihan 10 adalah sebagai default di Java mungkin karena array 10 kata 32-bit ditambah array / objek overhead cocok dalam garis cache 64 byte.
  • Berapa nilai ruang vs efisiensi runtime ? Jika Anda ingin kinerja runtime yang lebih baik, umumnya lebih baik untuk pra-mengalokasikan lebih banyak ruang untuk menghindari alokasi ulang tambahan nanti.

Sebagai hasil dari pertukaran ini, dapat dimengerti bahwa implementasi pengumpulan yang berbeda mungkin memiliki kapasitas default optimal yang berbeda.

mikera
sumber