editor php Apple memperkenalkan anda cara memadamkan elemen dengan cekap daripada kepingan dalam Go. Dalam bahasa Go, pemadaman elemen dalam hirisan adalah operasi biasa Walau bagaimanapun, disebabkan oleh ciri hirisan, pemadaman terus elemen boleh menyebabkan panjang hirisan berubah, sekali gus menjejaskan operasi seterusnya. Untuk memadamkan elemen dalam kepingan dengan cekap, kita boleh menggunakan ciri kepingan dan beberapa fungsi terbina dalam untuk mencapai ini. Beberapa kaedah yang biasa digunakan akan diperkenalkan secara terperinci di bawah.
Terdapat pelbagai cara untuk mengalih keluar elemen hirisan. Tetapi bagaimana jika saya mempunyai aplikasi yang melakukan banyak pemprosesan kepingan? Potongan Go dioptimumkan dengan baik untuk menambah elemen baharu, tetapi adakah terdapat cara yang cekap untuk mengalih keluar elemen daripada kepingan (bukan sahaja untuk kelajuan, tetapi juga dioptimumkan memori).
Saya sedar tentang kepingan. Padam fungsi yang diperkenalkan dalam Go 1.21, tetapi di sebalik tabir ia menggunakan teknik terkenal berikut:
return append(s[:i], s[j:]...)
Nampaknya tatasusunan asas tidak dikurangkan dalam kes ini. Ini bagus untuk kelajuan, tetapi bagaimana jika kita mempunyai banyak elemen (seperti 100k atau 1M) dan kemudian mengurangkannya kepada sangat sedikit (seperti hanya 10)? Nampaknya tiada pengoptimuman memori seperti yang digunakan untuk meningkatkan kapasiti kepingan.
Apabila kita tidak perlu mengekalkan susunan elemen dalam kepingan, kita boleh menggunakan kaedah berikut (pergi ke pautan taman permainan):
func sliceDel[S ~[]E, E any](s S, i, j int) S { lastIdx := len(s) - (j - i) copy(s[i:], s[lastIdx:]) return s[:lastIdx] }
Ini berguna apabila kita mempunyai kepingan besar dan sebilangan kecil elemen untuk dialih keluar (idea di sebaliknya adalah untuk menyalin sebilangan kecil elemen kepingan).
Mengenai memori, kapasiti adalah sama dalam kedua-dua kes dan tidak akan berkurangan. Contohnya:
// Reduce slice almost to zero for i := 0; i < sliceSize/2-1; i++ { sl = sliceDel(sl, 0, 2) } fmt.Printf("len = %d, cap = %d", len(sl), cap(sl)) // Output: len = 2, cap = 100000 // Reduce slice almost to zero for i := 0; i < sliceSize/2-1; i++ { sl = slices.Delete(sl, 0, 2) } fmt.Printf("len = %d, cap = %d", len(sl), cap(sl)) // Output: len = 2, cap = 100000
Jadi, adakah cara untuk mengoptimumkan penggunaan memori? Sebagai contoh, jika panjang kepingan kurang daripada separuh kapasitinya, kurangkan kapasiti sebanyak separuh.
Saya juga ingin tahu cara melakukan ini dengan cekap, seperti teknik seperti ini s[:len(s):len(s)]
(ungkapan kepingan penuh yang digunakan oleh kepingan.Klip) tidak mengurangkan tatasusunan asas - ia hanya menjimatkan kapasiti baharu dalam struktur kepingan untuk mengelakkan penambahan new Mengatasi elemen kepingan induk apabila elemen itu dilampirkan pada kepingan anak (seperti yang dinyatakan dalam cadangan ini).
Tiada penyelesaian "biasanya terbaik". Anda telah menunjukkan berbilang pendekatan dalam soalan anda, setiap satunya mungkin lebih baik daripada yang lain untuk senario tertentu.
Jika anda berada dalam situasi seperti ini, apabila anda ingin menyimpan beberapa elemen daripada banyak, jangan mula padam elemen tersebut. Bina kepingan baharu dengan unsur-unsur ini. Selain lebih pantas, ini pasti menyelesaikan masalah ingatan juga.
Anda tidak boleh mengurangkan penggunaan memori dengan menggunakan ungkapan kepingan penuh selain daripada memperuntukkan dan menggunakan kepingan baharu. Selagi terdapat rujukan kepada tatasusunan sokongan, ia tidak akan mengecut (sekurang-kurangnya tidak dalam versi semasa Go). Jika anda menghadapi situasi di mana tatasusunan sandaran yang besar diperuntukkan tetapi hanya sebahagian kecil daripadanya digunakan, anda boleh memperuntukkan sekeping baharu dan menyalin elemen secara manual untuk membolehkan tatasusunan besar dikumpul sampah.
Pertimbangkan juga bahawa jika anda mempunyai kepingan yang sangat besar yang mungkin anda perlukan untuk mengalih keluar banyak elemen, satu kepingan mungkin bukan struktur data terbaik untuk digunakan. Sebagai contoh, anda boleh cuba menggunakan senarai terpaut, atau anda juga boleh mencuba peta: memadamkan elemen daripada senarai terpaut atau peta akan menjadi lebih pantas dan pemetaan juga akan memberikan masa carian yang pantas (O(n)
), seperti yang ditunjukkan di bawah.
Atas ialah kandungan terperinci Bagaimana untuk mengalih keluar elemen dengan cekap daripada kepingan dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!