Dietrich Epp ile aynı fikirdeyim: GHC'yi hızlı yapan birkaç şeyin birleşimi .
Her şeyden önce Haskell çok üst düzey. Bu, derleyicinin kodunuzu bozmadan agresif optimizasyonlar yapmasını sağlar .
SQL'i düşünün. Şimdi, bir SELECT
ifade yazdığımda , zorunlu bir döngü gibi görünebilir , ama değil . Bu olabilir gibi bakmak belirtilen koşullara uygun olan birini bulmaya çalışırken o tablodaki tüm satırların üzerine döngüler, ancak aslında tamamen farklı performans özelliklerine sahip - "derleyici" (DB motoru) araması yerine bir dizin yapıyor olabilir. Ancak SQL çok yüksek düzeyde olduğundan, "derleyici" tamamen farklı algoritmaların yerine geçebilir, birden çok işlemci veya G / Ç kanalı veya tüm sunucuları şeffaf bir şekilde uygulayabilir .
Haskell'i aynı olarak düşünüyorum. Sen belki düşünmek sadece, ikinci listeye girdi Harita listesine üçüncü listeye ikinci listeye filtre ve sonra sonuçlandı kaç öğe saymak Haskell istedi. Ancak GHC'nin perde arkasındaki akış-füzyon yeniden yazma kurallarını uyguladığını görmediniz, her şeyi tek bir dar makine kod döngüsüne dönüştürerek tüm işi, tahsis olmaksızın verilerin üzerinden tek bir geçişte gerçekleştirecek - bu tür bir şey el ile yazmak için sıkıcı, hataya yatkın ve bakım gerektirmeyen olmak. Bu sadece koddaki düşük düzeyli ayrıntıların olmaması nedeniyle gerçekten mümkündür.
Buna bakmanın bir başka yolu da olabilir… Haskell neden hızlı olmasın ? Onu yavaşlatan ne yapar?
Perl veya JavaScript gibi yorumlanmış bir dil değil. Java veya C # gibi bir sanal makine sistemi bile değil. Tamamen yerel makine koduna kadar derler, böylece orada ek yük yoktur.
OO dillerinin aksine [Java, C #, JavaScript…], Haskell tam tip silme özelliğine sahiptir [C, C ++, Pascal…]. Tüm tür denetimi yalnızca derleme zamanında gerçekleşir. Yani sizi yavaşlatmak için çalışma zamanı türü denetimi yok. (Bu konuda boş-işaretçi kontrolü yoktur. Örneğin Java'da JVM, boş işaretçiler olup olmadığını kontrol etmeli ve birini iptal ederseniz bir istisna atmalıdır. Haskell bu denetimle uğraşmak zorunda değildir.)
"Çalışma anında anında fonksiyonlar yaratmanın" yavaş geldiğini söylüyorsunuz, ancak çok dikkatli bakarsanız, aslında bunu yapmazsınız. Göründüğün gibi görünebilir , ama yapmazsın. Eğer derseniz (+5)
kaynak kodunuzda kodlanmıştır. Çalışma zamanında değişemez. Yani bu gerçekten dinamik bir işlev değil. Kavisli fonksiyonlar bile parametreleri sadece bir veri bloğuna kaydediyor. Yürütülebilir kodun tamamı derleme zamanında mevcuttur; çalışma zamanı yorumu yoktur. ("Eval işlevi" olan diğer dillerden farklı olarak.)
Pascal'ı düşün. Eski ve kimse artık bunu gerçekten kullanmıyor, ancak kimse Pascal'ın yavaş olduğundan şikayet etmiyordu . Bu konuda hoşlanmayacak çok şey var, ama yavaşlık aslında onlardan biri değil. Haskell, elle bellek yönetimi yerine çöp toplama dışında, Pascal'dan farklı bir şey yapmıyor. Ve değişmez veriler, GC motorunda [tembel değerlendirme biraz karmaşıklaşır] birkaç optimizasyona izin verir.
Sanırım Haskell gelişmiş ve sofistike ve üst düzey görünüyor ve herkes "oh vay, bu gerçekten güçlü, inanılmaz derecede yavaş olmalı! " Diye düşünüyor. Ama öyle değil. Ya da en azından beklediğiniz gibi değil. Evet, inanılmaz bir tip sistemi var. Ama biliyor musun? Bütün bunlar derleme zamanında gerçekleşir. Çalışma zamanı geldiğinde gitti. Evet, bir kod satırı ile karmaşık ADT'ler oluşturmanıza izin verir. Ama biliyor musun? Bir ADT sadece düz sıradan C union
arasında struct
s. Başka bir şey yok.
Gerçek katil tembel bir değerlendirmedir. Kodunuzun kesinliğini / tembelliğini doğru bulduğunuzda, hala zarif ve güzel olan aptalca hızlı kod yazabilirsiniz. Ancak bu şeyleri yanlış anlarsanız, programınız binlerce kez daha yavaş gider ve bunun neden olduğu açık değildir.
Örneğin, her baytın bir dosyada kaç kez göründüğünü saymak için önemsiz küçük bir program yazdım. 25KB giriş dosyası için, programın çalışması 20 dakika sürdü ve yutuldu 6 gigabayt RAM'i ! Bu çok saçma !! Ama sonra sorunun ne olduğunu anladım, tek bir patlama deseni ekledim ve çalışma süresi 0,02 saniyeye düştü .
İşte Haskell beklenmedik bir şekilde yavaş ilerliyor. Ve buna alışmak biraz zaman alır. Ancak zamanla, gerçekten hızlı kod yazmak daha kolay hale gelir.
Haskell'i bu kadar hızlı yapan nedir? Saflık. Statik tipler. Tembellik. Ancak her şeyden önce, derleyicinin kodunuzun beklentilerini bozmadan uygulamayı kökten değiştirebileceği kadar yüksek düzeyde olmak.
Ama sanırım bu sadece benim fikrim ...