SORU
24 EYLÜL 2011, CUMARTESİ


F# vs Bunun: Yığın taşması

Geçenlerde F# for Python programmers ve bunu izledikten sonra hakkında bir sunum "" on my own. karınca bulmaca için bir çözüm uygulamak için karar verdi bulundu

Etrafında düzlemsel bir ızgara üzerinde yürümekte olan bir karınca var. Karınca bir zaman, sağa, yukarı veya aşağı bir boşluk taşıyabilirsiniz. Yani, hücre (x, y) karınca gidebilir hücreleri (x 1, y), (x-1, y), (x, y 1) ve (x, y-1). X ve y rakamları toplamı koordinat nerede puan 25 karınca ulaşılmaz olan daha büyüktür. Örneğin, nokta (59,79) 25'den büyük olan 5 9 7 9 = 30, çünkü erişilemiyor. Soru: Kaç Puan (1000, 1000) de dahil olmak üzere (1000, 1000) başlarsa karınca erişim kendisini?

OCaml first 30 hat benim çözümüm uygulanan ve bunu denedik:

$ ocamlopt -unsafe -rectypes -inline 1000 -o puzzle ant.ml
$ time ./puzzle
Points: 148848

real    0m0.143s
user    0m0.127s
sys     0m0.013s

Temiz, benim sonuç leonardo's implementation, in D and C ile aynı. Leonardo'nun C uygulama için karşılaştırma, Bunun Versiyon 2 kat daha yavaş C den yaklaşık çalışır . TAMAM, leonardo bir kuyruk özyineleme kaldırmak için kullanılan göz önüne alındığında.

Ben o zaman 9 * ... * ve ben burada ne var:

Thanassis@HOME /g/Tmp/ant.fsharp
$ /g/Program\ Files/FSharp-2.0.0.0/bin/fsc.exe ant.fs
Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

Thanassis@HOME /g/Tmp/ant.fsharp
$ ./ant.exe

Process is terminated due to StackOverflowException.
Quit

Thanassis@HOME /g/Tmp/ant.fsharp
$ /g/Program\ Files/Microsoft\ F#/v4.0/Fsc.exe ant.fs
Microsoft (R) F# 2.0 Compiler build 4.0.30319.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

Thanassis@HOME /g/Tmp/ant.fsharp
$ ./ant.exe

Process is terminated due to StackOverflowException

Yığın taşması... F her iki sürümü ile# ben makinem var... Meraktan soruyorum, ben daha sonra oluşturulan ikili (ant.exe aldı ve çalıştırın Kemerin altında Linux/Mono:

$ mono -V | head -1
Mono JIT compiler version 2.10.5 (tarball Fri Sep  9 06:34:36 UTC 2011)

$ time mono ./ant.exe
Points: 148848

real    1m24.298s
user    0m0.567s
sys     0m0.027s

Şaşırtıcı bir şekilde, Mono 2.10.5 (yani yığın taşması hayır) altında çalışır ama 84 saniye, yani 587 kez Bunun daha yavaş oops alır.

Bu program

  • Bunun altında iyi çalışır
  • hiç altında çalışmıyor .NET/F#
  • çalışıyor, ancak çok yavaş, Mono/F altında#.

Neden?

DÜZENLEME:Gariplikler devam ediyor - "----optimize" sorun yok . kontrol Kullanarak ^strong>ama sadece ArchLinux altında/Mono; altında Windows XP ve Windows 7/64 bit, ikili yığın taşması optimize edilmiş sürümü bile.

Son DÜZENLEME: Ben aşağıda cevabını görmek öğrendim.

CEVAP
30 EYLÜL 2011, Cuma


Yönetici özeti:

  • Bir algoritmanın basit bir uygulama... bu kuyruk özyinelemeli olmadığını yazdım.
  • Linux altında Bunun ile derlenmiş.
  • İyi çalıştı, ve 0.14 saniyede bitirdi.

F noktası için zaman oldu#.

  • F (doğrudan çeviri) kodu çevirdim#.
  • Windows altında derlenmiş ve çalıştırın - bir yığın taşması var.
  • Linux altında ikili aldım ve Mono altında çalıştırın.
  • İşe yaradı ama çok yavaş (84 saniye) çalıştırın.

O zaman ben Yığın Taşması ilan - ama bazı insanlar soru (nefes) kapatma kararı.

  • --Optimize ile derleme --işaretli . denedim
  • İkili hala Windows altında yığın doldu...
  • ...ama çalışma güzel (0.5 saniyede bitirdi Linux altında Mono.

Bu yığın boyutunu kontrol etmek için zaman oldu: Windows Altında another SO post pointed out that it is set by default to 1MB. Linux altında "ve a compilation of a test program 8 MB net bir şekilde ortaya koydu."- s uname

Bu program Windows (program stack 1MB daha fazla kullanılır) altında Linux altında değil, neden işe yaradığı açıkladı. Olmadı sana neden en iyileştirilmiş sürümü çalıştırmak çok daha altında Mono daha olmayan optimize edilmiş bir: 0.5 saniye vs 84 saniye bile olsa --optimize görünür olması için ayarlayın varsayılan olarak, bakın yorum Keith ile "Uzman F#" özü). Muhtemelen bir şekilde 1 sürümü ile aşırı tahrik olan Mono çöp toplayıcısı ile bir ilgisi yoktur.

/Bunun ve Linux/Mono/F Linux arasındaki fark# yürütme zamanı (0.14 vs 0.5) ölçtüm basit, çünkü biri: "zaman ./ikili ..." Mono için önemli olan başlangıç saati, kirlenmis.NET (Peki, bu ufacık sorun için önemli.

Her neyse, bunu çözmek için ilk ve son kez, ben wrote a tail-recursive version - özyinelemeli çağrı sonunda fonksiyonudur dönüştürülmüş bir döngü (ve bu nedenle, hiçbir yığın kullanımı gerekli - en azından teoride).

Yeni sürüm Windows altında sorunsuz olarak çalıştırmak, ve 0.5 saniyede bitirdi.

Yani, bu hikayeden alınacak ders şu:

  • Senin dikkat özellikle eğer çok fazla kullanırsanız yığın kullanımı ve Windows altında çalışır. EDITBIN with the /STACK option ikili daha büyük boyutlarda, ya da, çok fazla kullanmaya bağımlı olmayan bir şekilde kod yazmak daha da iyi yığın yığın ayarlamak için kullanın.
  • Bunun daha iyi olabilir at kuyruk özyineleme F daha eleme# - ya da çöp toplayıcı bu sorunu daha iyi bir iş yapıyor.
  • Eğer bu sorular gerçekten iyi olup olmadığını hakkında umutsuzluk ...kaba insanlar Yığın Taşması soru, iyi insanlar onları sonunda etkisini ortadan kaldıracaktır kapanış -: - yok)

S. S. Dr. Jon Bazı ek giriş Harrop:

...sadece Bunun taşma yoktu şanslısınız. Zaten gerçek yığın boyutları platformlar arasında farklılık tespit edilmiştir. Aynı sorunun başka bir yönüdür farklı dil uygulamaları olduğunu farklı oranlarda yığın alanı ve farklı performansa sahip yemek stoklarla huzurunda özellikleri. Bunun, Mono ve .NET tüm farklı veri gösterimleri kullanma ve GC etkileyen algoritmaları bu sonuçlar... (a) Bunun tagged tamsayı işaretçisi ayırt etmek için kullanır, veren kompakt yığın çerçeveler ve gez her şey yığını olacak göstericiler arıyor. Etiketleme aslında sadece yeterince bilgi aktarıyor o zaman Bunun öbek traverse (b) edebilmek için çalıştırmak için Mono kelimeler davranır bir işaretçi olarak, bir kelime nokta ise muhafazakar bir işaretçi yığını üzerinde: içine öbek ayrılan blok o blok erişilebilir kabul edilir. (c) bilmiyorum .NET ama eğer yığın yemiş olursa hiç şaşırmam algoritması. uzayda daha hızlı ve hala yığın (kesinlikle her sözü geçilen eğer alakasız bir iplik varsa, GC, patolojik performans düşer derin yığın!)... Ayrıca, öbek ayrılan kullanmanız anlamına gelir dizilerini çabuk kreş nesil (örn gen0 doldurma ve, bu nedenle, traverse o derin yığınlar genellikle GC neden...

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • 8bitdigitaltv

    8bitdigitalt

    31 AĞUSTOS 2011
  • Jimmie Jones

    Jimmie Jones

    16 Kasım 2007
  • The Pet Collective

    The Pet Coll

    5 Ocak 2012