Swift Academy · Pelajaran

MemoryLayout dan Penjajaran

Periksa saiz, stride dan penjajaran jenis.

Pelajaran 1 daripada 413 langkah

MemoryLayout dan Penjajaran ialah pelajaran Swift Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Swift Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Swift Academy merangkumi sejumlah 4 pelajaran.

Mengapa Susun Atur Memori Penting

Apabila anda bekerja dengan Swift yang tidak selamat atau menjambatani C, anda perlu mengetahui cara nilai disusun dalam memori. Swift menyediakan MemoryLayout<T> untuk memeriksa perkara ini tanpa menyentuh bait raw.

Ia menjawab tiga soalan: berapa besar sesuatu nilai, sejauh mana jarak antara nilai dalam tatasusunan, dan pada sempadan alamat manakah sesuatu nilai mesti bermula.

// MemoryLayout works on any type
print(MemoryLayout<Int>.size)       // 8 on 64-bit
print(MemoryLayout<Bool>.size)      // 1
print(MemoryLayout<Double>.size)    // 8

size — Storan Sebenar

MemoryLayout<T>.size ialah bilangan bytes yang digunakan oleh data penting sesuatu nilai. Ia tidak termasuk pad tambahan di hujung yang mungkin berada antara elemen dalam tatasusunan.

Gunakan size apabila anda ingin mengetahui jumlah bytes bermakna yang disimpan oleh satu nilai.

struct Point {
    var x: Int8   // 1 byte
    var y: Int64  // 8 bytes
}

print(MemoryLayout<Point>.size)   // 16 (not 9 — padding!)

stride — Jarak dalam Tatasusunan

stride ialah jarak dalam bytes antara permulaan satu elemen dengan elemen seterusnya apabila nilai disusun dalam tatasusunan bersebelahan. Nilainya sama dengan size yang dibundarkan ke atas mengikut alignment.

Apabila anda memperuntukkan penimbal secara manual, darabkan dengan stride, dan jangan sekali-kali dengan size.

print(MemoryLayout<Point>.stride) // 16
print(MemoryLayout<Int8>.stride)  // 1

// Buffer for 10 Points needs:
let bytes = 10 * MemoryLayout<Point>.stride // 160

alignment — Sempadan Alamat

alignment ialah sempadan bait tempat sesuatu nilai mesti bermula. Nilai integer 64-bit dengan alignment 8 mesti bermula pada alamat yang boleh dibahagi dengan 8. Pengkompil memasukkan pad untuk mematuhi syarat ini.

Alignment sesuatu struktur ialah alignment terbesar antara ahlinya.

print(MemoryLayout<Int8>.alignment)   // 1
print(MemoryLayout<Int64>.alignment)  // 8
print(MemoryLayout<Point>.alignment)  // 8

Perbezaan size dengan stride

Bagi banyak jenis, size == stride, tetapi kedua-duanya berbeza apabila terdapat pad. Sesuatu struktur mungkin mempunyai size 9 tetapi stride 16 kerana elemen seterusnya mesti sejajar pada sempadan 8 bait.

Panduan umum: gunakan size untuk memahami satu nilai dan stride untuk memahami koleksi.

struct Mixed {
    var flag: Bool   // 1
    var value: Int   // 8
}
print(MemoryLayout<Mixed>.size)   // 16
print(MemoryLayout<Mixed>.stride) // 16

Offset Medan

Bagi struktur, anda boleh mengetahui kedudukan setiap sifat tersimpan berbanding permulaan menggunakan MemoryLayout<T>.offset(of:) dengan laluan kunci. Ini penting apabila menyusun data agar sepadan dengan struktur C.

struct Header {
    var magic: UInt32  // offset 0
    var length: UInt64 // offset 8 (padded)
}

print(MemoryLayout<Header>.offset(of: \Header.magic) ?? -1)  // 0
print(MemoryLayout<Header>.offset(of: \Header.length) ?? -1) // 8

Menyusun Semula untuk Menjimatkan Ruang

Disebabkan alignment, susunan sifat tersimpan mempengaruhi size. Meletakkan medan yang lebih besar dahulu atau mengumpulkannya mengikut size boleh mengecilkan struktur. Perkara ini penting bagi tatasusunan besar kerana bytes yang dibazirkan akan terkumpul.

struct Wasteful { var a: Int8; var b: Int64; var c: Int8 } // size 24
struct Tight    { var b: Int64; var a: Int8; var c: Int8 } // size 16

print(MemoryLayout<Wasteful>.size)
print(MemoryLayout<Tight>.size)

Susun Atur Rujukan

Sesuatu tika kelas diperuntukkan pada timbunan, jadi pemboleh ubah yang menyimpan rujukan kelas hanyalah sebuah penuding. MemoryLayout.sizenya ialah saiz penuding, iaitu 8 bytes, tanpa mengira saiz objek tersebut.

Jenis nilai seperti struktur menyimpan kandungannya secara sebaris; jenis rujukan hanya menyimpan penuding.

class Big { var data = [Int](repeating: 0, count: 1000) }

print(MemoryLayout<Big>.size) // 8 — just the reference

Nilai Pilihan dan Enumerasi

Nilai pilihan biasanya menambah satu bait untuk penanda, tetapi Swift mengoptimumkan nilai pilihan rujukan dengan menggunakan semula penuding null, jadi String? boleh mempunyai size yang sama seperti String.

Enumerasi dengan nilai berkaitan disukat untuk menyimpan kes terbesarnya bersama diskriminator.

print(MemoryLayout<Int?>.size)    // 9
print(MemoryLayout<String>.size)  // 16
print(MemoryLayout<String?>.size) // 16 — no extra byte

Menggunakan Bentuk Berasaskan Contoh

Setiap ahli (size, stride, alignment) juga mempunyai bentuk berasaskan contoh: MemoryLayout.size(ofValue:). Ini berguna apabila jenis sukar dinyatakan sepenuhnya atau dibuat kesimpulan secara automatik.

let tuple = (UInt8(1), UInt64(2))
print(MemoryLayout.size(ofValue: tuple))      // 16
print(MemoryLayout.stride(ofValue: tuple))    // 16
print(MemoryLayout.alignment(ofValue: tuple)) // 8

Memperuntukkan dengan Susun Atur yang Betul

Apabila anda memperuntukkan memori raw, anda mesti memberikan kedua-dua bilangan bytes dan alignment. Mendapatkan nilai ini daripada MemoryLayout menjamin ketepatan merentas seni bina, berbanding menetapkan nombor secara manual.

let count = 4
let capacity = count * MemoryLayout<Int>.stride
let align = MemoryLayout<Int>.alignment

let raw = UnsafeMutableRawPointer.allocate(
    byteCount: capacity, alignment: align)
defer { raw.deallocate() }

Semak Pantas

Uji pemahaman anda tentang size berbanding stride.

Imbas Kembali

Anda telah mempelajari tiga asas susun atur memori:

  • size — bytes bermakna bagi satu nilai
  • stride — jarak antara elemen tatasusunan (gunakan ini untuk peruntukan)
  • alignment — sempadan permulaan yang diperlukan

Anda juga telah melihat offset(of:) untuk kedudukan medan, cara susunan sifat mempengaruhi size, dan bahawa rujukan hanya bersaiz penuding. Alat ini membolehkan anda memperuntukkan dan mentafsir memori raw dengan selamat.

Percuma untuk bermula

Pelajari Swift dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
122
Pelajaran
409

Soalan Lazim

Adakah pelajaran “MemoryLayout dan Penjajaran” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Swift Academy, termasuk “MemoryLayout dan Penjajaran”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Swift Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “MemoryLayout dan Penjajaran”?

Periksa saiz, stride dan penjajaran jenis. Anda berlatih Swift Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Swift Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Swift Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “MemoryLayout dan Penjajaran” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Swift Academy ini?

Ya. Setiap pelajaran Swift Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. MemoryLayout dan Penjajaran
  2. UnsafePointer dan UnsafeMutablePointer
  3. Penuding Penimbal Tidak Selamat
  4. withUnsafeBytes dan Interop C
← Kembali ke Swift Academy