Rust'ta derleyici, veri hizalaması ve yapıların yanı sıra enum'ların yerleşim olanakları hakkında bilgi kullanarak bellek içinde verileri verimli bir şekilde yerleştirmeye çalışır. Bu konu, düşük seviyeli ve sistem düzeyinde geliştirmelerde özellikle önemlidir; çünkü türlerin aşırı boyutu, bellek israfına yol açar.
Otomatik hizalama, çoğu dilin bir özelliğidir; ancak Rust'ta derleyici, yerleşim (layout) hakkında sıkı garantiler sağlar (prime optimizasyona izin verir) ve enum'lar durumunda, tüm seçenekler için maksimum boyutu dikkate alarak bellek birleştirerek kompakt depolamayı gerçekleştirmektedir.
Yapı veya enum'daki alanların sırası ve türleri, hizalama özellikleri nedeniyle türün nihai boyutunu etkiler. Yanlış bir sıralama, "padding" — kullanılmayan baytların artmasına neden olur. İlişkilendirilmiş verilere sahip enum'larda, maksimum seçenek boyutu belirler ve bazı yapılar enum'ları beklenmedik şekilde hacimli hale getirebilir.
Alanların sırasını doğru belirtmek ve türleri seçmek, verilerin boyutunu std::mem::size_of ile analiz etmek önemlidir. Enum'lar için, iç içe yapı ve işaretçilerle dikkatli olunmalıdır.
Kod örneği:
struct Bad { a: u8, // 1 bayt + 7 bayt padding b: u64, // 8 bayt } struct Good { b: u64, // 8 bayt, en baştan hizalama a: u8, // 1 bayt + 7 bayt padding sonunda }
Boyut kontrolü:
use std::mem::size_of; println!("{}", size_of::<Bad>()); // 16 bayt println!("{}", size_of::<Good>()); // 16 bayt (ancak padding şimdi sonunda)
Enum için:
enum Example { Unit, Num(u32), Pair(u64, u8), } println!("{}", size_of::<Example>()); // boyut — max(variantes ölçüsü) + discriminant
Ana özellikler:
Yapıdaki u8 ve u64 alanlarının sırası değiştirilirse, yapının boyutu değişecek mi?
Hayır, toplam boyut hala maksimum alanın hizalama birimi ile katlanmış olarak kalacaktır; ancak padding kayması olacaktır. Bu, yapı başka bir yapıya dahil ediliyorsa veya FFI'ye geçiriliyorsa önemlidir.
Küçük bir enum'un büyük bir bellek boyutu olabilir mi?
Evet, eğer en az bir seçenek büyük bir nesne veya referans içeriyorsa, enum'un toplam boyutu, en "ağır" seçeneği ile ve discriminant ile olacaktır.
Yapının düzeni her zaman tüm platformlarda aynı mı?
Hayır, düzen ve hizalama mimariler arasında farklılık gösterebilir. Sıkı kontrol için repr(C) özelliği kullanılır.
#[repr(C)] struct MyFFIStruct { x: u32, y: u8, }
Büyük koleksiyonlarda, nadiren karşılaşılan bir iç içe Vec ile birlikte enum kullanılır; ancak bu enum'un boyutunu 10 kat artırır. Bellek gereksiz yere harcanır.
Artılar:
Eksiler:
Enum, daha küçük birkaç enum'a ayrılır, diziler/kolleksiyonlar ayrı ya da nadir seçimler için Box aracılığıyla saklanır, düzen #[repr(C)] ile kontrol edilir. Boyut size_of ile kontrol edilmiştir.
Artılar:
Eksiler: