Niedawno znalazłem prezentację o F# for Python programmers, a po jej obejrzeniu zdecydowałem się na samodzielne wdrożenie rozwiązania "mrówki".F # vs OCaml: Stack overflow
Istnieje mrówka, która może chodzić po planarnej kratce. Mrówka może poruszać się o jedno pole w lewo, w prawo, w górę lub w dół. Oznacza to, że z komórki (x, y) mrówka może przejść do komórek (x + 1, y), (x-1, y), (x, y + 1) i (x, y-1). Punkty, w których suma cyfr współrzędnych x i y jest większa niż 25, jest niedostępna dla mrówki. Na przykład punkt (59,79) jest niedostępny, ponieważ 5 + 9 + 7 + 9 = 30, który jest większy niż 25. Pytanie brzmi: Ile punktów może mieć dostęp do mrówki, jeśli zaczyna się od (1000, 1000), w tym (1000, 1000)?
I wdrożone moje rozwiązanie w 30 liniach OCaml first i spróbował go:
$ ocamlopt -unsafe -rectypes -inline 1000 -o puzzle ant.ml
$ time ./puzzle
Points: 148848
real 0m0.143s
user 0m0.127s
sys 0m0.013s
Neat, mój wynik jest taki sam jak leonardo's implementation, in D and C++. W porównaniu do implementacji C++ leonarda, wersja OCaml działa około 2 razy wolniej niż C++. Co jest w porządku, biorąc pod uwagę, że Leonardo używał kolejki do usuwania rekursji.
Potem translated the code to F# ... i oto co mam:
[email protected] /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.
[email protected] /g/Tmp/ant.fsharp
$ ./ant.exe
Process is terminated due to StackOverflowException.
Quit
[email protected] /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.
[email protected] /g/Tmp/ant.fsharp
$ ./ant.exe
Process is terminated due to StackOverflowException
przepełnienie stosu ... obiema wersjami F # mam w moim komputerze ... z ciekawości, ja potem wziął generowane binarne (ant.exe) i uruchomić go pod Arch 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
Niespodziewanie biegnie pod Mono 2.10.5 (czyli bez przepełnienia stosu) - ale to trwa 84 sekund, czyli 587 razy wolniej niż OCaml - oops.
Więc ten program ...
- działa poprawnie pod SML
- nie działa w ogóle pod .NET/C#
- działa, ale jest bardzo powolny, pod Mono/F #.
Dlaczego?
EDIT: Weirdness kontynuuje - Używanie "--optimize + --checked-" sprawia, że problem zniknie, ale tylko pod ArchLinux/Mono; pod Windows XP i Windows 7/64bit, nawet zoptymalizowana wersja przepełnienia stosu binarnego.
Ostateczna edycja: Sam dowiedziałem się odpowiedzi - patrz poniżej.
Nie widzę pytania lub po prostu go przeczytam. Wygląda na to, że jest tylko rantem i złym. Możesz pomyśleć o wypróbowaniu tego przy pomocy odpowiedniego zestawu ustawień optymalizacyjnych (generowanie wywołań rekurencyjnych przypominających ogon) - ale bez kodu, który ma opowiadać na stronie z często zadawanymi pytaniami? – Carsten
Kod znajduje się w linkach do pastebin. – ttsiodras
Ale nie ma wątpliwości, że jest to cały punkt stackoverflow. Głosuję, aby to zamknąć. – talonmies