İlkay İlknur

just a developer...

Compile Time Constants(const) vs Runtime Constants(readonly)

Merhaba Arkadaşlar,

Kimi zaman uygulamalarımız içerisinde gerçekleştirmiş olduğumuz uygulamanın domainine bağlı olarak ta bir takım sabit değerler kullanabilmekteyiz. (Her ne kadar bu şekilde değerlerin de ileride uygulamanın değişme ve gelişme olasılığını düşünerek parametrik olarak bir yerlerden değiştirilebilmesini yapmamız gerekse de şimdilik bu noktayı pas geçelim ;) )

C# tarafından baktığımızda da uygulama içerisinde sabit değer tanımlamak için kullanabileceğimiz 2 yöntem bulunmakta.

Bunlar,

  • Compile - Time Constants (const)
  • Runtime Constants (readonly)

Şimdi sırayla bu yöntemleri inceleyelim.

Compile - Time Constants (const)

Compile - time constants dediğimizde aslında değeri derleme zamanında belli olan sabitlerden bahsetmekteyiz. C# içerisinde const keywordünü kullanarak uygulamamız içerisinde derleme zamanı sabitlerden tanımlayabilmekteyiz. Derleme zamanı sabitlerinin değerlerini de tanımlama yaptığımız anda vermek zorundayız !

[sourcecode language="csharp"] public const double Pi=3.14; [/sourcecode]

Şimdi isterseniz bu değeri Console'a yazdıran ufak bir uygulama yazalım ve sonrasında Reflector ile arka planda açalım.

[sourcecode language="csharp"] private static void Main(string[] args) { Console.WriteLine((double)3.14); } [/sourcecode] Uppss ! Tanımlamamız nereye gitti :) Aslında baştan beri bahsetmiş olduğumuz compile time constant kavramının özeti bu. Bu sabitin değeri derleme sırasında belli olduğu için compiler bu sabitin kullanıldığı yerlerde değeri otomatik olarak kendisi yazmakta. Böylece bellekte de herhangi bir bölgeye erişme ve değeri oradan okuma gibi bir uygulama bulunmamakta. Özetlememiz gerekirse compiler, const ile tanımladığımız compile - time constanların değerlerini derleme sırasında kullanıldığı yerlere doğrudan eklemekte. Bunun ne gibi avantajları ve dezavantajları var birazdan inceleyeceğiz. Şimdi bir de runtime - constanlara bakalım...

Runtime - Time Constants (readonly)

Yukarıda yapmış olduğumuz sabit değişken tanımlama işinin aynısını bu sefer de runtime constant kullanarak yapalım. Runtime constantları da C# içerisinde readonly keywordünü kullanarak tanımlayabiliriz.

[sourcecode language="csharp"] public static readonly double Pi = 3.14; [/sourcecode]

Reflector ile uygulamamızı açtığımızda bu sefer aşağıdaki gibi bir durumla karşılaşmaktayız.

[sourcecode language="csharp"] private static void Main(string[] args) { Console.WriteLine(Pi); } [/sourcecode] Bu durumda ise aslında uygulamamız beklediğimiz şekilde merkezi bir değişkene erişip bu değişkenin değerini runtime'da alarak kullanıyor olacak. Bu nedenle bu değişkeni runtime içerisinde belirleyebilme imkanına sahibiz. Tabi bu belirleme işini en fazla constructora kadar erteleyebiliyoruz. :)

Compile Time Constants vs Runtime Constants

Şimdi gelelim bu sabit tanımlama yöntemlerinin karşılaştırmasına.

Compile time constantlara baktığımızda aslında compile zamanında belli olmaları nedeniyle kullanıldıkları yerlerde doğrudan kullanılmaktalar. Bu nedenle de performans açısından daha önde olduklarını söylememiz herhalde yanlış olmaz. Sonuçta bellek erişimi yapmıyoruz. Bunun yanında düşünmemiz gereken kritik bir senaryo bulunmakta.

Elimizde bir class library bulunduğunu düşünelim ve bu class library içerisinde de compile time constant tanımlandığını varsayalım. Sonrasında ise console uygulamamıza da bu class library'i referans olarak ekleyelim ve uygulama içerisinde de bu class library içerisinde ki sabitin içeriğini ekrana yazdırdığımızı düşünelim. Uygulamayı ilk geliştirdiğimiz sırada bu şekilde tanımlamamızı yaptığımızı, uygulamayı da derleyip deploymentını yaptığımızı varsayalım :)

Ancak zaman ilerledikçe bu sabit değerimiz değişti ve biz de class library içerisindeki değeri güncelleyip, bu class library 'i uygulamamızın çalıştığı dizine kopyaladık.(Sonuçta değişikliği sadece bu library içerisinde yaptık). Uygulamamız çalışmaya devam etti ancak baktığımızda ekranda değişkenin hala daha eski değerinin yazıldığını görüyor oluruz. Bunun nedeni de tabi compile time constant olduğu için kullanıldığı yere derleme sırasındaki değerin yazılmasıdır. Yeniden bir derleme yapılmadığı sürece de bu değerin değişmesinin imkanı yok.

Bu nedenle compile time constantları kullanırken dikkat etmemiz gereken nokta ise şu olmalıdır : Uygulamamızın versiyonları arasında değişmeyecek olan sabitleri compile - time constant kullanarak tanımlamamız gerekir.Örneğin Pi sayısı gibi.

Yazımızı bitirirken son bir özet yapmamız gerekirse compile time constantlar runtime constantlara nazaran daha hızlıdırlar. Ancak güncellenmeleri sırasında yukarıda bahsetmiş olduğumuz gibi durumlarla karşılaşma ihtimali oldukça yüksektir. Bu nedenle değeri hiçbir zaman değişmeyecek sabitlerin tanımında kullanılmalıdırlar ya da uygulamamız performans kritik bir uygulama ise ancak bu şekilde bir kullanım kabul edilebilir olabilir.

Runtime constantlar nispeten daha yavaş olsalar da bahsetmiş olduğumuz kullanım şekillerini düşündüğümüzde güncellemeler sırasında yukarıda bahsetmiş olduğumuz durumlarla karşılaşmıyoruz.

Çok performans kritik uygulamaları dışarıda bırakırsak sabit tanımlamaları sırasında runtime constantların kullanılmasını tavsiye etmekteyim. Sonuçta yavaş ama doğru çalışan bir uygulama , hızlı ama kararsız ve yanlış çalışan uygulamadan çok çok daha iyidir. ;)

Görüşmek Üzere,



Yorum Gönder


Yorumlar

  • profile

    fuat tatar

    • 19
    • 9
    • 2012

    Teşekkür ederim gerçekten yararlı oldu benim için. Ama açıkçası pi sayısı gibi değeri değişmeyecek olan sabitler için Compile Time Constants kullanmak daha mantıklı gibi.

  • profile

    İlkay İlknur

    • 12
    • 6
    • 2012

    @Cihan :) Çok acımasız olur :D

  • profile

    Cihan Yakar

    • 11
    • 6
    • 2012

    Öyle ki bir class library'i sadece const değerleri tutmak amacıyla kullanırsanız, derlenmiş uygulama o library'e artık ihtiyaç duymayacağından dosyayı (.dll) sildiğiniz halde uygulama hiç bir şey olmamış gibi -öyle aslında- çalışmaya devam edecektir. Bu demo öğrenci için oldukça şaşırtıcıdır :)