Image 179
Swift Programlama Dilinde Method Dispatch Teknikleri

Merhabalar,

Bu blog yazımızda, Method Dispatch’in ne olduğunu ve Swift programlama dilinde kullanılan farklı Method Dispatch tekniklerini inceleyeceğiz. Bir method çağrıldığında arka planda neler oluyor hep birlikte inceleyelim.

Method Dispatch Nedir?

Method dispatch (gönderim yöntemi), bir mesaja yanıt olarak hangi yöntemin çağrılması gerektiğine karar vermek için kullanılan bir algoritmadır.

Konumuz özelinde dispatch kavramı; bir nesne üzerinden nesnenin ait olduğu class veya super class’ının herhangi bir fonksiyonunun çağırılma sürecinde, memory’deki hangi kodun adresine gidilip çalıştırılacağına karar verilmesi işlemidir. Kodun adresinin CPU’ya verilmesi, gönderim işleminin amacıdır. Swift uygulama geliştirme dilinin kullandığı 3 temel method dispatch yöntemi vardır.

1.    Static method dispatching

Static dispatch, direct veya compile-time dispatch olarak da adlandırılabilir. Direct dispatch, en hızlı method dispatch yöntemidir. Peki bu hız nereden geliyor?

Static method dispatching, adından da anlaşılacağı üzere çalışacak metotların adreslerinin hafızada önceden bilindiği ve metot çağırıldığı anda hangi adreste saklanan komutların işleneceğinin derleme zamanında belli olduğu gönderim yöntemidir. Fonksiyonlar bu yöntemde override edilemediği için, derleyici hafızada tek bir yerde tutulduğunu bilerek direk olarak o adrestekini bulunup çalıştırır.

  • En hızlısı olmasının yanında derleyicinin inlining veya devirtualization gibi farklı türde optimizasyonlar gerçekleştirmesine de olanak tanır. Inlining, derleme zamanında bir fonksiyon çağrısını fonksiyonun tümü ile değiştirilmesi işlemidir. Devirtualization ise derleyicinin fonksiyonu hafızadan direkt olarak çağırabileceği bir kopyasını oluşturmasıdır.
  • Ek olarak, programlama açısından en kısıtlayıcı olanıdır ve alt sınıflandırmayı destekleyecek kadar dinamik değildir.
  • Static dispatch yöntemi, hem değer tipleri (value types) hem de referans tipleri (reference types) tarafından desteklenir.

2.    Dynamic method dispatching

Dynamic dispatch, table veya run-time dispatch olarak da adlandırılabilir. Bu yöntem, sadece referans tipleri tarafından desteklenir. Çünkü değer tipleri kalıtımı desteklememektedir.

Dynamic method dispatching ise bir metot çağırıldığı anda, hafızadaki hangi adreste yer alan kodun çalışacağına çalışma zamanında (run-time) dinamik olarak karar veren gönderim yöntemidir. Bu karar, derleme zamanı (compile-time) yerine çalışma zamanında alındığı için performans açısından bir yük oluşturmaktadır. Diğer yandan bu yöntem, kalıtıma olanak sağladığı için nesne tabanlı programlama dillerinin (OOP) çoğu tarafından desteklenmektedir. 

V-Table (Virtual Table)

Dynamic dispatch ile ilgili bilmemiz gereken en önemli kavram virtual (witness) tablolarıdır. Bir sınıfın içerisinde tanımlanan her fonksiyonun bir sanal tablosu vardır. Bu tablo, fonksiyonun adreslerini tutar.

Bu tablolar ile ilgili önemli noktalar:

  • Derleme zamanında (compile time) da oluşturulur.
  • Her bir alt sınıfın kendi tablosunun kopyası vardır.
  • Alt sınıfa eklenen her bir yeni method için işaretçi (pointer), dizinin sonuna eklenir.
  • Derleyici, çalışma zamanında (run-time) tablodaki adresleri kullanır.

Şekil 2: Virtual (Sanal) Tablo Örneği

3.    Message Dispatching

Objective-C, Message Dispatching yöntemini kullanır. Swift dilinden Objective-C runtime’da geçebildiğimiz için Swift dili 3 gönderim tipini de destekler hale gelir.

Message Dispatch tekniği en dinamik tür olmasına rağmen, diğer tüm gönderim türleri arasında en yavaş olanıdır. Bunun temel nedeni, dynamic dispatchte uygulama derleme aşamasında bir sanal (virtual) tablosu oluşturulabiliyorken, message dispatchte, şifrelenmiş olabileceği veya yeni yöntemler eklenmiş olabileceği için hangi yöntemin çağrılacağına karar vermek mümkün değildir.

Bu yöntem, hangi fonksiyonun kullanılacağını bulabilmek için sınıf hiyerarşisinden yararlanır.

Şekil 3: Method Pointer Dizi Yapısı Örneği

Method Swizzling

Objective C nin desteklediği mesaj gönderim yöntemi, bir fonksiyonun çalışma zamanında (run-time) işlevselliğinin değiştirilmesine olanak sağlar. Bu özelliğe method swizzling denmektedir.

SIL (Swift Intermediate Language) Belgeleri

Peki biz hangi gönderim yönteminin kullanıldığını nasıl anlayabiliriz? Burada SIL belgeleri bize yardımcı olacaktır.

SIL belgesi, Swift programlama dilini uygulamak için tasarlanmış, yüksek düzeyde anlamsal bilgiye sahip, SSA biçiminde bir IR (Intermediate Representation) çıktısıdır.

  • Eğer bir fonksiyon dynamic dispatch yöntemini kullanıyorsa SIL belgesi v-table (witness table) içermelidir.

Şekil 4: v-table örneği
  • Eğer message dispatch kullanılıyorsa, volatile, foreign ve objc_method anahtar sözcükleri bulunmalıdır.

Şekil 5: volatile, foreign anahtar sözcük örneği
  • Son olarak, eğer yukarıda bahsettiğimiz durumlardan herhangi biri yoksa static dispatch yöntemi kullanılıyor anlamına gelmektedir.

Örnekler

Value Types (Değer Türleri)

  • struct ve enum değer türleri olduğundan ve kalıtımı desteklemediğinden, derleyici alt sınıflara ayrılamayacağını bilerek statik gönderim yöntemini kullanır.

Şekil 6: Value Types Örneği

Protocol

  • Protocoller dynamic dispatch yöntemini kullanır.
  • Extension içerisinde tanımlanan herhangi bir method için static dispatch yöntemi kullanılır.

Şekil 7: Protocol Örneği

Class (Sınıf)

  • @objc kullanıldığı zaman Message dispatch yöntemi kullanılır.
  • Bir sınıfı final olarak işaretlersek, o sınıf alt sınıflara ayrılamaz ve dolayısıyla Static Dispatch kullanılır.

Tablo 1. Method Dispatch tekniklerinin özeti

Dynamic Dispatch Kullanımı Azaltılarak Performansı Artırma

  • Bir tanımın override edilmeye gerek olmadığı bilindiği zaman final anahtar kelimesi kullanılmalıdır. Final, bir sınıfın, fonksiyonun veya özelliğin (property) override edilemeyeceğini belirten bir kısıtlamadır. Bu, derleyicinin dynamic dispatch i güvenli bir şekilde atlamasına olanak tanır.
  • Private anahtar sözcüğünün bir method veya değişkene uygulanması, tanımın geçerli olduğu dosyadaki görünürlüğünü kısıtlar. Bu kısıtlama, derleyicinin potansiyel olarak override edilen tüm tanımları aramasına olanak sağlar. Tanımın override edildiği bir yer bulunursa derleme hatası verir, bulunmazsa, final anahtar sözcüğünü otomatik olarak kullanabileceği sonucuna varır ve bu şekilde işaretler. Son olarak derleyici, dolaylı çağrıları kaldırır.
  • Bir sınıf içerisindeki tüm tanımlara özel bir erişim belirleyici belirtilmediğinde varsayılan internal olacaktır. Derleyici, internal olan tüm tanımları, her sınıf için ayrı modüller yerine tek bir modül olarak derleyecektir. Buna Tüm Modül Optimizasyonu (Whole Module Optimization) denir. Bu teknik sayesinde derleyici, bir modülün tüm dosyalarını bir bütün olarak optimize etmiş olur.

Sonuç olarak, bu yazıda nesne tabanlı programla dillerinden olan Swift’te method gönderimin ne olduğu ve kaç farklı gönderim türünün desteklendiğini inceledik.

Performans ve dolayısıyla hız açısından static dispatch bu yöntemlerin arasında büyük bir öneme sahiptir. Bu yöntem için, Swift dilini Objective – C ile kıyasladığımızda neden daha hızlı olabileceği ile ilgili bir fikir verdi diyebiliriz. Dynamic dispatch yöntemi, kalıtıma olanak sağladığı için nesne tabanlı programlama dilleri için önemli bir gönderim yöntemidir. Message dispatch ise daha az performanslı gibi görünse de bir dizi harika tekniğe olanak tanıyan büyük bir esneklik sunuyor.

Bu yazı, method dispatch in uygulama geliştirirken ne kadar önemli olduğunu vurguluyor. Bu yöntemleri bilmek, daha optimize edilmiş ve performanslı kod yazmamızı sağlayacaktır.

Kaynaklar

  1. https://medium.com/@venki0119/method-dispatch-in-swift-effects-of-it-on-performance-b5f120e497d3#:~:text=Method%20dispatch%20is%20the%20algorithm,particular%20method%20call%20in%20memory. (Erişim Tarihi: 01.12.2023)
  2. https://developer.apple.com/swift/blog/?id=27 (Erişim Tarihi: 01.12.2023)
  3. https://mobikul.com/method-dispatch-in-swift/ (Erişim Tarihi: 01.12.2023)
  4. https://medium.com/@bakshioye/static-vs-dynamic-dispatch-in-swift-a-decisive-choice-cece1e872d (Erişim Tarihi: 01.12.2023)
  5. https://medium.com/@pallavidipke07/method-dispatch-in-swift-b113a40a713a (Erişim Tarihi: 01.12.2023)
Şengül Büşra Bakkal
Nisan 28 , 2024
Diğer Blog İçerikleri