Recentemente ho trovato una presentazione su F# for Python programmers e, dopo averlo visto, ho deciso di implementare una soluzione al "puzzle delle formiche" per conto mio.F # vs OCaml: overflow dello stack
C'è una formica che può camminare su una griglia planare. La formica può muovere uno spazio alla volta a sinistra, a destra, in alto o in basso. Cioè, dalla cellula (x, y) la formica può andare alle celle (x + 1, y), (x-1, y), (x, y + 1) e (x, y-1). I punti in cui la somma delle cifre delle coordinate xey sono maggiori di 25 non sono accessibili alla formica. Ad esempio, il punto (59,79) è inaccessibile perché 5 + 9 + 7 + 9 = 30, che è maggiore di 25. La domanda è: Quanti punti può accedere alla formica se inizia a (1000, 1000), incluso (1000, 1000) stesso?
ho implementato mia soluzione in 30 righe di OCaml first e provato fuori:
$ ocamlopt -unsafe -rectypes -inline 1000 -o puzzle ant.ml
$ time ./puzzle
Points: 148848
real 0m0.143s
user 0m0.127s
sys 0m0.013s
accurato, il mio risultato è lo stesso di quello di leonardo's implementation, in D and C++. Paragonato all'implementazione del C++ di leonardo, la versione di OCaml funziona circa 2 volte più lentamente del C++. Che è OK, dato che Leonardo ha usato una coda per rimuovere la ricorsione.
Ho poi translated the code to F# ... ed ecco quello che ho ottenuto:
[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
Stack overflow ... con entrambe le versioni di F # che ho nella mia macchina ... per curiosità, ho poi preso la generato binario (ant.exe) ed eseguirlo sotto 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
Sorprendentemente, gira sotto Mono 2.10.5 (cioè senza overflow dello stack) - ma ci vogliono 84 secondi, vale a dire 587 volte più lento OCaml - oops.
Quindi questo programma ...
- funziona bene sotto OCaml
- non funziona affatto in .NET/F #
- opere, ma è molto lento, sotto Mono/F #.
Perché?
EDIT: Stranezze prosegue - Usando "--optimize + --checked-" rende il problema scompare, ma solo sotto ArchLinux/Mono; sotto Windows XP e Windows 7/64bit, anche la versione ottimizzata dello stack binario trabocca.
Final EDIT: Ho scoperto la risposta da solo - vedi sotto.
Io non vedo nessuna domanda o l'ho appena sovrapposto. Sembra solo che sia uno sproloquio e uno cattivo. Potresti pensare di provare questo con le giuste impostazioni di ottimizzazione impostate (generare chiamate ricorsive in coda), ma senza codice che deve essere indicato su un sito di domande frequenti? – Carsten
Il codice è lì, nei collegamenti a pastebin. – ttsiodras
Ma non c'è dubbio, che è l'intero punto dello stackoverflow. Sto votando per chiudere questo. – talonmies