Kapan boleh menggunakan Array Paralel?

14

Saya telah menjalankan kode (kode baru) yang menggunakan apa yang saya sebut 'Array Paralel' atau Daftar. Berarti ada 2 array yang berisi data terkait dan dihubungkan oleh posisi mereka (indeks) dalam array.

Saya menganggap ini membingungkan dan rentan terhadap segala macam kesalahan. Solusi yang biasanya saya usulkan adalah membuat objek yang disebut Companydengan bidang CompanyId dan CompanyName.

Contoh yang sangat nyata:

List<string> companyNames;
List<int> companyIds;

//...They get populated somewhere and we then process

for(var i=0; i<companyNames.Count; i++)
{
    UpdateCompanyName(companyIds[i],companyNames[i]);
}

Apakah array paralel ini dianggap praktik buruk ?

APK
sumber
9
Bukti lebih lanjut bahwa tidak ada bahasa yang ditemukan di mana Anda tidak dapat menulis Fortran.
andy mango
3
Mungkin ada (sangat signifikan) manfaat caching untuk melakukan sesuatu seperti ini (meskipun Anda perlu array yang berdekatan tidak terkait daftar), dan ini telah menjadi agak populer dalam pemrograman game yang terkait dengan "desain berorientasi data". Namun, ini sepertinya tidak berlaku untuk kasus Anda. Sepertinya Anda tidak membuat kode kritis kinerja.
Derek Elkins meninggalkan SE
2
@DerekElkins ... Menarik bahwa komentar Anda mengikuti salah satu yang membandingkan ini dengan kode Fortran. Fortran versi awal tidak memiliki dukungan untuk struktur yang ditentukan pengguna, dan bahkan setelah itu ditambahkan kode Fortran idiomatik menggunakan banyak array properti bukan array struktur. Dan ini sering dianggap sebagai bagian dari alasan Fortran sering dianggap sebagai bahasa tercepat.
Jules
3
Sebuah pemikiran yang bersinggungan dengan pertanyaan ini: banyak bahasa fungsional secara aktif mendorong bekerja dengan daftar tersebut. Mereka memiliki fungsi, biasanya disebut zip, yang mengubahnya menjadi daftar tupel. Kode Anda terlihat seperti C #. Versi terbaru dari C # telah menambahkan dukungan untuk tupel kelas satu. Saya ingin tahu apakah, oleh karena itu, mereka telah menambahkan fungsi zip di suatu tempat yang dapat membuat daftar Anda menjadi struktur yang berguna bagi Anda secara otomatis?
Jules
4
Yah, kadang-kadang ada alasan untuk menggunakan dua array secara sengaja, tetapi dalam 99% dari semua kasus saya telah melihat ini, satu-satunya alasan untuk itu adalah kemalasan penulis asli untuk memperkenalkan struktur data merangkul.
Doc Brown

Jawaban:

23

Berikut adalah beberapa alasan mengapa seseorang mungkin menggunakan array parrel:

  1. Dalam bahasa yang tidak mendukung kelas atau struct
  2. Untuk menghindari penguncian utas saat masing-masing utas hanya memodifikasi salah satu kolom
  3. Ketika metode kegigihan memaksa benda-benda ini disimpan secara terpisah dan Anda menyusunnya kembali.
  4. Mereka dapat mengkonsumsi lebih sedikit memori jika strukturnya empuk. (tidak berlaku untuk tipe data ini dalam C #)
  5. Ketika bagian dari data perlu disimpan berdekatan untuk membuat penggunaan CPU cache yang efisien (tidak akan membantu dalam kode di atas).
  6. Penggunaan kode op Single Instruction Multiple Data (SIMD). (tidak berlaku untuk kode ini, atau string sama sekali)

Saya tidak melihat alasan kuat untuk melakukan ini dalam kasus ini ... dan ada kemungkinan pilihan yang lebih baik di semua di atas atau tidak begitu berguna dalam bahasa tingkat tinggi.

TheCatWhisperer
sumber
3
Mereka dapat mengkonsumsi lebih sedikit memori juga jika strukturnya empuk. Beberapa array besar, yang dialokasikan secara cerdas, dapat mengkonsumsi lebih sedikit memori daripada berbagai struktur.
Frank Hileman
4
4. Ketika bagian dari data perlu disimpan berdekatan untuk membuat penggunaan CPU cache secara efisien. (Diperlukan dalam kasus yang jarang terjadi.)
Blrfl
@ Frank Hileman, Whilie Saya pikir jawaban oleh TheCatWhisperer sepenuhnya benar, komentar Anda sebenarnya adalah alasan terbaik untuk memilih pendekatan ini. Jika konsumsi memori sangat penting, overhead memori pada bantalan struct dapat menjadi signifikan, terutama jika sejumlah besar sedang bermain.
Vladimir Stokic
Menambahkan saran Anda ke jawabannya
TheCatWhisperer
Re (2), Bagaimana? Saya bisa menulis sebuah program dengan array tunggal struct dan kunci per bidang semudah saya bisa menulis satu dengan banyak array dan kunci per array.
Solomon Slow
7

Saya bersalah menggunakan array paralel . Kadang-kadang Anda masuk ke dalam struktur begitu banyak sehingga Anda tidak ingin berpikir tentang cara abstrak itu. Abstraksi bisa sedikit lebih sulit untuk refactor sehingga Anda enggan untuk memulai sampai Anda telah membuktikan apa yang benar-benar Anda butuhkan.

Pada titik itu, ada baiknya mempertimbangkan refactoring untuk meringkas detailnya. Seringkali alasan terbesar saya enggan melakukannya ternyata adalah sulit untuk memikirkan nama yang baik.

Jika Anda dapat melihat cara yang baik untuk abstrak array paralel pergi lakukan setiap waktu. Tetapi jangan melumpuhkan diri Anda dengan menolak untuk menyentuh mereka. Terkadang sedikit kode kotor adalah batu loncatan terbaik ke kode hebat.

candied_orange
sumber
6

Pola ini kadang-kadang juga disebut Struktur Array (bukan Array of Structures), dan sangat berguna ketika membuat vektor kode. Daripada menulis perhitungan yang berjalan pada struktur tunggal dan membuat vektor bit-bitnya, Anda menulis perhitungan seperti biasanya, kecuali dengan SSE intrinsik sehingga beroperasi pada 4 struktur, bukan satu. Ini biasanya lebih mudah, dan hampir selalu lebih cepat. Format SoA membuat ini sangat alami. Ini juga meningkatkan penyelarasan, yang membuat operasi memori SSE lebih cepat.

Dan
sumber
Ya, pendekatan ini digunakan saat melakukan pembelajaran mesin pada GPU. Merupakan kebiasaan untuk memisahkan bidang dari banyak contoh terpisah, mengemas semua nilai dari masing-masing bidang ke dalam tensor terpisah, dan meneruskan tensor tersebut untuk dihitung secara massal untuk menghasilkan daftar prediksi.
Pasang kembali Monica