Photo by Skitterphoto: https://www.pexels.com/photo/war-museum-perspective-army-9250/

Clean Code Performansın Düşmanı mı?

Clean Code performansın düşmanı mı? Takım arkadaşlarımla bu konuyu konuştuğumda “Evet, tabii ki düşmanı.” cevabını aldım. Takım arkadaşımız kendinden bu kadar emin konuştuğunda genellikle ona inanırız. Ama benim ikna olmam biraz zaman aldı. Bir şeyi temiz olarak betimliyorsak nasıl daha kötü olabilir? Aklıma ilk şu cevap geliyor; Clean Code pratikleri okunabilirliği, bakımı ve test edilebilirliği kolaylaştırıyor. Bu sebeple bir taraftan bize avantaj sağlarken diğer taraftan bize dezavantaj sağlayabilir.

Ama kod yazıp performans metriklerini karşılaştırmadan kendimi ikna edemezdim. Bu sebeple geçtim bilgisayar başına, açtım ideyi ve size bu hikayeyi hazırladım. Hadi başlayalım. ⬇️

Not : Çok fazla detaya girmeyeceğim, bunun yerine kıyaslamalar ve gerçek hayattan örneklerle konuyu betimlemeye çalışacağım.

İlk örnekte extract method kavramı ile başlayacağım. En çok karşılaştığım ve en çok düzelttiğim kod blokları genelde bu şekilde bitiyor. “Neden ayrı bir yöntem değil?”

Makale boyunca kullanacağımız ve statik veri üreten bir sınıf ile işe başlayalım.

Data.cs

Data.cs üzerinde bulunan veriler içerisinde renk bilgisini toplayan bir yordam geliştirelim ve sonrasında onu biraz daha okunaklı bir hale çevirelim.

GetAllCars yordamı static olarak yerleştirdiğimiz veriler üzerinde iki adet loop kullanarak renk bilgilerini list of string tipinde olan bir değişkene aktarıyor. Extract Method refactoring tekniği ile bu yordamı aşağıdaki hale çevirebiliriz.

Extract Method herkes tarafından bilinen ama çok az uygulanan bir yöntem.
Bakalım Clean Code kavramının en temel maddelerinden birini uyguladığımızda performansımız nasıl etkilenmiş.

Extract Method yönteminin uygulandığı yordam, tek bir metot olan yapıdan daha hızlı çıktı. 😯😯 “Clean Code performansın düşmanı mıdır?”

Hemen kabullenmeyelim ve neden daha hızlı olduğunu inceleyelim.

Method Inlining

JIT compiler kullanan herhangi bir dilde,

Metotların çağrılarını gövdeleriyle değiştirerek derlenmiş kaynak kodunu çalışma zamanında optimize etmenin bir yoludur.

Yani method inlining bizim için bir avantaj sağlıyor. Bu özellik sayesinde ara kod oluşurken optimizasyon gerçekleşiyor. Örneğin JAVA dilinde bu JWM’in görevidir.

Biraz daha işleri zorlaştıralım, Method Inlining olmadan performans nasıl olur sorusunu inceleyelim.

Optimizasyon aşamasında alt yordamların dahil edilmemesi için MethodImpl özniteliğini kullanacağız.

Artık JIT compiler ara kod oluşturmadan önce optimizasyon yapmayacak. Hadi sonuçları tekrar gözden geçirelim. 🧐

Vaaaaavvv😱 gerçekten “clean code performansın düşmanıymış” diyebilirsiniz ancak hayatımızda bu optimizasyon var. 😇

Yani metotlarınızı anlamlı olacak şekilde parçalayabilirsiniz. Endişelenmenize gerek yok. En azından Clean Code felsefesinin ilk adımını gerçekleştirmiş olursunuz. Makale içerisinde gerçekleştirdiğimiz örnek gerçek hayatta bire bir benzeri olan bir örnek olmayabilir. Sizin örneklerinizde başka bir servise istek atılıyor veya bir dosya işlemi gerçekleşiyor olabilir. Belki farklı kod bloklarında bu deneyi uyguladığınızda clean olarak nitelendirdiğiniz bölümün daha yavaş çalıştığını görebilirsiniz. Bu yazının temel amacı “Clean Code performansın düşmanıdır.” cümlesinin insanların gözünde “Artık hiç clean code yazmayacağım çünkü performanslı olmasını istiyorum.” gibi bir algı oluşmasını engellemektir.

İkinci deneyde oldukça sık kullanılan MediatR kütüphanesini kullanarak basit bir CQS yapısı kurmaya çalışacağım. Karşı tarafta direkt service call gerçekleştiren bir yapı bizi bekliyor olacak.

MediatR oldukça popüler bir kütüphane. Temel görevi arabuluculuk yapmak.

Command ve Query operasyonlarını ayırmak için oldukça basit ve hızlı bir çözüm sunuyor. Avantajları arasında decoupled kod geliştirminizi sağlamak bulunuyor. Ayrıca handler mekanizması sayesindeSingle Responsibility prensibini daha yaygın kullanmanızı sağlıyor.

CQS-CQRS ve MediatR ile ilgili daha fazla bilgi için bu adresi ziyaret edebilirsiniz.

MediatR kütüphanesinin çalışması temelde Dictionary yapısından geçer. Uygulama çalışırken handler yapıları bir dictionary üzerine aktarılır. Nesneler publish edildiğinde önce dictionary üzerinden ilgili servis bulunur ve operasyon başlatılır.

Karşı tarafta direkt ilgili sınıf üzerinde bulunan yordamı direkt çağıran bir yapı var.

İşlem adımları MediatR yapısında çok fazla. MediatR çok genel bir sorunu çok zarif bir şekilde çözebildiği için oldukça sık kullanılıyor. Tahmin etmek çok zor olmamalı. Büyük ihtimalle performans olarak işlem adımı sayısı yüzünden kaybeden taraf olacak. 😥

Yaklaşık üç katı daha kötü. 😥 “Clean Code performansın düşmanıdır.” Hadi sonuç kısmında konuyu netleştirelim.

Clean Code pratikleri genellikle kodunuzun daha okunabilir, test edilebilir ve bakım yapılabilir bir hale gelmesini hedefler. Hedefi performans optimizasyonu yapmak değildir. Bu sebeple hedefi olmayan bir pratiği sanki hedefiymiş ama yapamıyormuş gibi algılamak oldukça yanlış olacaktır.

C#, Java gibi yüksek seviyeli diller kullanıyorsanız önem vermeniz gereken şey süreklilik olmalıdır. Yukarıda bulunan ekran görüntülerin tamamında nanosaniye cinsinden bahsediyoruz. 1 Nanosecond (0.000000001 sec) yani çok küçük bir rakam. Tabii bu rakamlar yoğun yük altında uygulamalara tahmin edemeyeceğimiz sorunlar çıkarabilir ancak bunun suçlusu Clean Code teknikleri/felsefesi değildir. Meslek hayatım boyunca Clean Code veya Clean Architecture’a sahip olduğu için performans açısından sınıfta kalan bir uygulama görmedim. Artık kendimizi kandırmayı bırakmalıyız. Bu cümlenin arkasına saklanıp kötü kokan kod bloklarını olduğu gibi bırakmamalıyız. Yaptığımız işi daha temiz ve daha okunaklı hatta en önemlisi daha kolay bakım yapılabilecek bir hale dönüştürmeliyiz.

Yukarıda bahsedilen rakamlar farklı örneklerde enteresan sonuçlar üretebilir. Ancak refactoring ve clean code prensiblerini uyguladığınız kod blokları normalden çok uzakta olmayacaktır. Genellikle kabul edilebilir bir hata payı olarak nitelendirilecekdir.

İyi kurgulanmış, yeni gelen özelliklere çevik bir şekilde cevap verebilen mimariler uzun vadede performansını koruyacaktır. Tam tersi senaryoda klasik “yeniden yazıyoruz” eylemi ile karşı karşıya kalabilirsiniz.

Yazdığınız kodlar production ortamında hatasız koşsun, testler sizi korusun. 🙏

--

--

Medium independent DevOps publication. Join thousands of aspiring developers and DevOps enthusiasts

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Furkan Güngör

Furkan Güngör

Solution Developer — I want to change the world, give me the source code.