Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk Mendapatkan Slice Byte daripada Go String tanpa Menyalin Menggunakan `tidak selamat`?

Bagaimana untuk Mendapatkan Slice Byte daripada Go String tanpa Menyalin Menggunakan `tidak selamat`?

Barbara Streisand
Barbara Streisandasal
2024-11-01 01:51:28913semak imbas

How to Obtain a Byte Slice from a Go String without Copying Using `unsafe`?

Menggunakan Tidak Selamat untuk Mendapatkan Slice Byte daripada Rentetan tanpa Menyalin

Rentetan Go tidak boleh berubah, bermakna menukarkannya kepada kepingan bait melibatkan salinan memori. Ini berpotensi memberi kesan kepada prestasi apabila bekerja dengan set data yang besar. Artikel ini meneroka cara menggunakan tidak selamat untuk mengelakkan operasi penyalinan ini sambil menekankan aspek kritikal dan had.

Latar Belakang

Fungsi perpustakaan standard []bait(s) mencipta salinan rentetan s . Jika penggunaan memori membimbangkan, adalah wajar untuk mendapatkan kepingan bait tanpa menanggung overhed ini.

Penukaran Tidak Selamat

Menggunakan pakej tidak selamat menyediakan cara untuk mencapai matlamat ini. Dengan menghantar nilai rentetan ke penuding kepada tatasusunan bait, kita boleh mengakses kepingan bait asas tanpa membuat salinan.

<code class="go">func unsafeGetBytes(s string) []byte {
    return (*[0x7fff0000]byte)(unsafe.Pointer(
        (*reflect.StringHeader)(unsafe.Pointer(&s)).Data),
    )[:len(s):len(s)]
}</code>

Awas

Adalah penting untuk ambil perhatian bahawa pendekatan ini membawa risiko yang wujud. Rentetan dalam Go tidak boleh diubah, jadi mengubah suai hirisan bait yang diperoleh melalui unsafeGetBytes boleh mengakibatkan tingkah laku yang tidak dijangka atau bahkan rasuah data. Oleh itu, teknik ini hendaklah digunakan hanya dalam persekitaran dalaman terkawal di mana prestasi memori adalah yang paling penting.

Mengendalikan Rentetan Kosong

Perhatikan bahawa rentetan kosong ("") tidak mempunyai bait, jadi medan datanya adalah tidak tentu. Jika kod anda mungkin menemui rentetan kosong, menyemaknya secara eksplisit adalah penting.

<code class="go">func unsafeGetBytes(s string) []byte {
    if s == "" {
        return nil // or []byte{}
    }
    return (*[0x7fff0000]byte)(unsafe.Pointer(
        (*reflect.StringHeader)(unsafe.Pointer(&s)).Data),
    )[:len(s):len(s)]
}</code>

Pertimbangan Prestasi

Walaupun penukaran ini mengelakkan overhed penyalinan, adalah penting untuk diingat bahawa pemampatan operasi, seperti yang anda nyatakan menggunakan gzipWriter, adalah intensif dari segi pengiraan. Potensi keuntungan prestasi daripada mengelakkan salinan memori mungkin boleh diabaikan berbanding pengiraan yang diperlukan untuk pemampatan.

Pendekatan Alternatif

Sebagai alternatif, fungsi io.WriteString boleh dimanfaatkan untuk menulis rentetan ke io .Penulis tanpa menggunakan operasi salinan. Fungsi menyemak kewujudan kaedah WriteString pada io.Writer dan memanggilnya jika tersedia.

Soalan dan Sumber Berkaitan

Untuk penerokaan lanjut, pertimbangkan sumber berikut:

  • [Go GitHub Issue 25484](https://github.com/golang/go/issues/25484)
  • [unsafe.String](https://pkg.go.dev/ unsafe#String)
  • [unsafe.StringData](https://pkg.go.dev/unsafe#StringData)
  • [[]bait(rentetan) lwn []bait(*rentetan) )](https://stackoverflow.com/questions/23369632/)
  • [Apakah kemungkinan akibat menggunakan penukaran yang tidak selamat daripada []bait kepada rentetan dalam go?](https://stackoverflow.com /questions/67306718/)

Atas ialah kandungan terperinci Bagaimana untuk Mendapatkan Slice Byte daripada Go String tanpa Menyalin Menggunakan `tidak selamat`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn