SQLite neden C ile yazıldı?
(sqlite.org)- SQLite, performans, uyumluluk, düşük bağımlılık ve kararlılık nedeniyle en başından beri (2000) C dili ile geliştirildi
- C, neredeyse tüm işletim sistemlerinde ve dillerde kullanılabilir; özellikle düşük seviyeli kütüphaneler için hızlı çalışmayı destekler
- Nesne yönelimli diller yerine C’nin seçilme nedeni; genişletilebilirlik, farklı dillerden çağrılabilme ve geliştirme döneminde C++ ile Java’nın henüz olgunlaşmamış olmasıydı
- SQLite, neredeyse hiç bağımlılığı olmayan tek dosyalık bir yapıya sahiptir ve yalnızca C standart kütüphanesinin en temel işlevlerini kullanır
- Rust ve Go gibi "güvenli diller" ile yeniden yazma tartışmaları olsa da kalite yönetimi, performans ve kütüphane olarak çağrılabilirlik açısından C hâlâ üstün kabul ediliyor
1. C neden en iyi seçimdi
- SQLite, 29 Mayıs 2000’deki ilk geliştirmesinden bu yana bugün hâlâ C diliyle sürdürülüyor
- Şu anda başka bir dilde yeniden yazma planı yok
- C, donanıma yakın denetim gücü sunarken aynı zamanda yüksek taşınabilirliğe sahip olduğu için “taşınabilir assembly dili” olarak anılır
- Başka diller “C kadar hızlıyız” diyebilir, ancak C’den daha hızlı olduğunu iddia eden bir dil yoktur
1.1. Performans
- SQLite gibi düşük seviyeli kütüphaneler sık sık çağrıldığından son derece hızlı çalışmaları gerekir
- C dili, hızlı kod yazmak için uygundur; hem yüksek taşınabilirlik sağlar hem de donanıma yakından erişebilir
- Diğer modern diller de “C kadar hızlı” olduklarını söylese de genel amaçlı programlamada C’den daha hızlı olduğundan emin olunan bir dil yoktur
- C, bellek ve CPU kaynaklarını ayrıntılı biçimde denetleyebildiği için dosya sisteminden %35 daha hızlı performans gösterebilir
- Örnek: Internal vs External BLOBs
1.2. Uyumluluk
- Neredeyse her sistem C ile yazılmış kütüphaneleri çağırabilir
- Örneğin Android’de (Java tabanlı) bile bir adaptor üzerinden SQLite kullanılabilir
- SQLite Java ile yazılmış olsaydı iPhone’da (Objective-C, Swift) kullanılamazdı; bu da genel kullanım alanını ciddi biçimde daraltırdı
1.3. Düşük bağımlılık
- C kütüphanesi olarak geliştirildiği için çalışma zamanı bağımlılıkları çok azdır
- En küçük yapılandırmada yalnızca standart C kütüphanesinin şu temel işlevleri kullanılır: memcmp(), memcpy(), memmove(), memset(), strcmp(), strlen(), strncmp()
- Daha tam özellikli derlemelerde bile malloc(), free(), dosya girdi/çıktısı gibi az sayıdaki bağımlılıkla yetinir
- Modern diller çoğu zaman çok sayıda büyük çalışma zamanı bileşeni ve binlerce arayüz gerektirir
1.4. Kararlılık
- C, eski, çok değişmeyen ve sıkıcı bir dil olabilir; ancak bu aynı zamanda öngörülebilirlik ve kararlılık anlamına gelir
- SQLite gibi küçük, hızlı ve güvenilir bir veritabanı motoru geliştirirken, standardı sık değişmeyen bir dil daha uygundur
- Dilin özellikleri ya da uygulamaları sık sık değişirse bu, SQLite’ın kararlılığı açısından olumsuz olur
2. Neden nesne yönelimli bir dille yazılmadı?
- Bazı geliştiriciler nesne yönelimli değilse SQLite gibi karmaşık bir sistemi kurmanın zor olduğunu düşünür; ancak C’ye kıyasla C++ ya da Java ile kütüphane yapmak, başka dillerden çağırmayı zorlaştırır
- Haskell, Java ve başka birçok dili desteklemek için C kütüphanesi seçimi mantıklıdır
- Nesne yönelimlilik bir dil değil, bir tasarım desenidir; dolayısıyla belirli bir dille sınırlı değildir
- C’de de struct ve function pointer kullanılarak nesne yönelimli desenler uygulanabilir
- Nesne yönelimlilik her zaman en iyi yapı değildir; kimi zaman prosedürel kod daha açık, daha kolay yönetilebilir ve daha hızlı sonuç verebilir
- SQLite’ın ilk geliştirildiği dönemde (2000 civarı)
- Java olgunlaşmamıştı
- C++’ta ise derleyiciler arası uyumluluk sorunları ciddiydi
→ O dönemde C, en pratik ve en güvenli seçimdi
- Bugün bile SQLite’ı yeniden yazmayı haklı çıkaracak kadar güçlü bir avantaj görünmüyor
3. Neden "güvenli bir dil" ile yazılmadı?
- Son yıllarda Rust ve Go gibi güvenli programlama dillerine ilgi artsa da SQLite ilk geliştirildiğinde (ilk 10 yılında) bu diller mevcut değildi
- Go ya da Rust ile yeniden yazılırsa daha fazla hata ortaya çıkma veya performansın düşme ihtimali vardır
- Bu diller bellek denetimi gibi ek branch kodları ekler; oysa SQLite’ın kalite stratejisinde %100 branch coverage çok önemlidir ve bu gereksinim burada karşılanmaz
- Güvenli diller genellikle out-of-memory durumunda programı sonlandırır; SQLite ise bellek yetersizliği durumundan kurtulabilecek şekilde tasarlanmıştır
- Rust, Go ve benzeri diller hâlâ görece yenidir ve gelişmeye devam etmeleri gerekir
- Bu yüzden SQLite geliştiricileri güvenli dillerin gelişimini desteklese de SQLite’ın uygulanmasında hâlâ kanıtlanmış C kararlılığını öncelikli görüyor
Buna rağmen, bir gün Rust ile yeniden yazılması yine de mümkün olabilir. Go’nun assert() sevmemesi nedeniyle Go ile yazılma olasılığı düşüktür
- Ancak Rust ile yazılabilmesi için bazı ön koşullar vardır:
- Rust’ın daha da olgunlaşması, değişim hızının yavaşlaması ve “eski, sıkıcı bir dil” hâline gelmesi
- Birden çok dilden çağrılabilen genel amaçlı bir kütüphane üretilebildiğinin kanıtlanması
- Gömülü sistemler gibi işletim sistemi olmayan aygıtlarda da çalışabilecek nesne kodu üretebilmesi
- Derlenmiş ikili dosyalar için %100 branch coverage test araçlarının bulunması
- OOM (bellek yetersizliği) hatalarından kurtulabilmesi
- SQLite’ta C’nin yaptığı her şeyi Rust’ın performans kaybı olmadan yapabilmesi
- Eğer bir Rust meraklısı (rustacean) bu koşulların zaten sağlandığını ve SQLite’ın Rust ile yeniden yazılması gerektiğini düşünüyorsa, SQLite geliştiricileriyle doğrudan iletişime geçip görüşünü savunması öneriliyor
2 yorum
Hacker News görüşleri
if (i >= array_length) panic("index out of bounds")gibi savunma kodları ekliyor ama o kodun kendisi zaten Rust derleyicisi tarafından iyi test edildiği için endişe etmeye gerek olmadığı düşünülüyor. Bu mantığı doğru anlayıp anlamadığından emin değilget_unchecked()gibi yöntemlerle bounds check olmadan erişim de mümkün; bununla hem güvenliği koruyup hem performansı artırmak mümkün olabilir get_unchecked belgeleriif condition { panic(err) }yapısının bir assert fonksiyonu gibi kullanılamayacağı merak ediliyorC’nin SQLite için de bir güvenlik riski olduğu ifadesi var; bu, testleri yeterince iyi yazsanız ve yeterince deneyimli geliştiriciler olsanız bile yine de geçerli mi? Sorun mantıkta ve geliştirme sürecinde olabilir, ancak dilin kendisinin bir güvenlik açığı olması bana anlaması zor geliyor. Aslında C ile yazılmış altyapıya dayanmayan program neredeyse yok denecek kadar az değil mi?