Cpp Sınıfı İçinde Global ve Yerel Değişken Kullanımı: Performans ve Hafıza Yönetimi
Yazılım geliştirme sürecinde, performans ve hafıza yönetimi hayati öneme sahiptir. Bu yazımızda, C++ programlama dilinde sınıf içinde global ve yerel değişken kullanımının performans ve hafıza yönetimi üzerindeki etkilerini detaylı bir şekilde ele alacağız. Ayrıca, bu konseptleri anlamak için basit ancak etkili örnek kodlar ve bu kodların assembly diline çevrilmiş hallerini inceleyeceğiz.
C++ Örnek Kod
#include <stdint.h>
struct LargeStruct {
uint64_t num1 = 0;
uint64_t num2 = 0;
uint64_t num3 = 0;
// Büyük bir veri bloğu
uint8_t data[10000] = {0};
};
class MyClass {
public:
void updateGlobalInstance();
void updateLocalInstance();
// Sınıf seviyesinde global bir örnek
LargeStruct globalInstance = {0};
};
void MyClass::updateGlobalInstance() {
// Global örneği güncelle
globalInstance.num1 = 0;
}
void MyClass::updateLocalInstance() {
// Fonksiyon seviyesinde yerel bir örnek
LargeStruct localInstance = {0};
localInstance.num1 = 0;
}
Assembly Dilindeki İki Fonksiyonun Karşılaştırılması ve Performans Etkileri
MyClass::updateGlobalInstance()
fonksiyonunun assembly dili çıktısı:
MyClass::updateGlobalInstance():
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], 0
nop
pop rbp
ret
MyClass::updateLocalInstance()
fonksiyonunun assembly dili çıktısı:
MyClass::updateLocalInstance():
push rbp
mov rbp, rsp
sub rsp, 10112
mov QWORD PTR [rbp-10104], rdi
lea rax, [rbp-10096]
mov edx, 10088
mov esi, 0
mov rdi, rax
call memset
mov QWORD PTR [rbp-10096], 0
nop
leave
ret
İlk fonksiyon (MyClass::updateGlobalInstance()
) ve ikinci fonksiyon (MyClass::updateLocalInstance()
) arasındaki en önemli fark, ikinci fonksiyonun daha fazla yerel depolama alanı kullanması ve bu nedenle daha fazla hafıza işlemi gerçekleştirmesi ve daha büyük bir stack frame oluşturmasıdır. Bu farklar performansa etki edebilir.
İkinci fonksiyonun assembly ifadeleri ve performans etkileri şu şekildedir:
sub rsp, 10112
: Bu komut, yerel depolama için 10112 bayt yer ayırır. Bu, büyük bir stack frame oluşturur ve bu nedenle daha fazla hafıza kullanır. Ayrıca, bu işlem işletim sistemi ve donanım tarafından gerçekleştirildiğinden bazı performans maliyeti vardır.mov QWORD PTR [rbp-10104], rdi
: Bu komut, girdi parametresini yerel depolama alanına kopyalar. Bu, hafıza erişimi gerektirir ve hafıza trafiği oluşturabilir.mov rax, QWORD PTR [rbp-10096]
vemov QWORD PTR [rbp-10096], 0
: Bu iki komut, yerel depolama alanında değer okuma ve yazma işlemleri gerçekleştirir. Hafıza erişimi gerektirir ve performans üzerinde etkisi olabilir.call memset
: Bu komut, yerel depolama alanını temizlemek içinmemset
işlevini çağırır. Bu işlem, büyük bir bellek bölgesini temizlemek için döngüsüz bir işlem yapar, bu nedenle performans açısından maliyetli olabilir.
Bu farklar, ikinci fonksiyonun daha fazla hafıza ve işlemci kaynağı kullanabileceği anlamına gelir. Büyük bir stack frame oluşturmak ve büyük bellek bölgelerini temizlemek, performansı etkileyebilir ve programın daha yavaş çalışmasına neden olabilir. Özellikle bu işlemler sık sık çağrılıyorsa veya büyük veri yapıları ile çalışılıyorsa, bu performans maliyeti daha da belirgin olabilir.
İşte bu tür durumlarda kodun optimize edilmesi ve hafıza yönetiminin dikkatli bir şekilde ele alınması önemlidir. Çünkü gereksiz büyük yerel depolama alanları ve gereksiz bellek temizleme işlemleri, programın performansını olumsuz etkileyebilir.
Hafıza Kullanım Akışı Diyagramı
Aşağıya tanımlamış olduğunuz verilerin dağılımı ve kullanımı ile ilgili bilgilendirici görseller ekliyorum.
Performans ve Hafıza Yönetimi
Bu iki fonksiyon ve onların assembly dili çıktıları, global ve yerel değişken kullanımının hafıza üzerinde nasıl farklılık gösterdiğini açıkça ortaya koyar. updateGlobalInstance
fonksiyonu, sınıfın global durumunu güncellerken, updateLocalInstance
fonksiyonu, her çağrıldığında büyük bir yerel yapı oluşturur ve bu, hafıza üzerinde önemli bir yük oluşturabilir.
- Global Değişken Kullanımı:
updateGlobalInstance
fonksiyonu, sınıfın zaten ayrılmış olan global bir örneğini günceller. Bu işlem, ek hafıza ayırma gerektirmez ve performans üzerinde minimal etkiye sahiptir. Ancak, global durumu dikkatli bir şekilde yönetmek önemlidir. - Yerel Değişken Kullanımı:
updateLocalInstance
fonksiyonu, her çağrıldığında yığın üzerinde yeni birLargeStruct
örneği oluşturur. Büyük yapılar için bu, önemli bir hafıza ve zaman maliyeti oluşturabilir. Fonksiyon sona erdiğinde, yerel değişkenler otomatik olarak temizlenir, bu da kodun temiz ve yan etkisiz olmasını sağlar.
Sonuç
C++’da global ve yerel değişken kullanımının, hafıza yönetimi ve performans üzerinde önemli etkileri vardır. Yazılım geliştiriciler, bu etkileri dikkate alarak, uygulamalarının gereksinimlerine en uygun çözümü seçmelidir. Aynı zamanda fonksiyonlarda çok büyük yapı ve sınıfları bünyesine parametre olarak almamalıdır.
Aşağıda Stack ve Heap hafıza alanlarını anlamak için faydalı bir video bulabilirsiniz.