åã®èšäºã§ãæ©èœçãã€èšèªæåã®ããã°ã©ãã³ã°ææ³ã䜿çšããŠãä»®æ³ã¹ã¿ãã¯ãã·ã³çšã®ããã°ã©ã ãšã°ãŒãã¥ãŒã¿ãŒãæ§ç¯ããæ¹æ³ã«ã€ããŠèª¬æããŸããã èšèªã®æ°åŠçæ§é ã¯ãã»ãã°ã«ãŒããšã¢ãã€ãã®æŠå¿µã«åºã¥ããŠããã®ç¿»èš³è
ã®å®è£
ã®åºæ¬æ§é ã瀺åããŸããã ãã®ã¢ãããŒãã«ãããçŸããæ¡åŒµå¯èœãªå®è£
ãæ§ç¯ããææãæã€ããšãã§ããŸããããèŽè¡ããã®æåã®è³ªåã¯æŒå£ãéããŠåã³Emacsã«ç»ããŸããã

ç°¡åãªãã¹ããå®æœããã¹ã¿ãã¯ã®ã¿ã䜿çšããåçŽãªã¿ã¹ã¯ã§ä»®æ³ãã·ã³ãã¹ããŒãã«åäœãããã¡ã¢ãªãïŒã©ã³ãã ã¢ã¯ã»ã¹ã®é
åïŒã䜿çšãããšå€§ããªåé¡ãçºçããããšã確èªããŸããã ããã°ã©ã ã®ã¢ãŒããã¯ãã£ã®åºæ¬ååãå€æŽããã«ãããã解決ããããã°ã©ã ã®ååã®é«éåãéæããæ¹æ³ã«ã€ããŠããã®èšäºã§èª¬æããŸãã
Haskellã¯ãç¹å¥ãªããããæã€ç¬ç¹ã®èšèªã§ãã ãã®äœæãšéçºã®äž»ãªç®æšã¯ãlingua francaãé¢æ°åããã°ã©ãã³ã°ã®ã¢ã€ãã¢ãè¡šçŸããã³ãã¹ãããå¿
èŠæ§ã§ããã ããã¯ããã®æãé¡èãªæ©èœãæ£åœåããŸãïŒæ inessãæ倧éã®çŽåºŠãåã®åŒ·èª¿ãããã³ãããã®æäœã ããã¯ãæ¥åžžã®éçºçšã§ã¯ãªããç£æ¥çšããã°ã©ãã³ã°çšã§ããåºã䜿çšããããã§ããããŸããã ãããã¯ãŒã¯æ¥çãããŒã¿åŠçã§å€§èŠæš¡ãããžã§ã¯ããäœæããããã«å®éã«äœ¿çšãããŠãããšããäºå®ã¯ãå¿
èŠã«å¿ããŠéçºè
ã®åæãæŠå¿µå®èšŒã§ãã ãããããããŸã§ã®ãšãããHaskellã§æžãããæãéèŠã§åºã䜿çšãããŠããé©ãã»ã©åŒ·åãªè£œåã¯... ghcã³ã³ãã€ã©ã§ãã ãããŠãããã¯ãã®ç®çã®èŠ³ç¹ããå®å
šã«æ£åœåãããŸã-ã³ã³ãã¥ãŒã¿ãµã€ãšã³ã¹ã®åéã®ç 究ã®ããã®ããŒã«ã«ãªãããšã ãµã€ã¢ã³ã»ãã€ãã³ã»ãžã§ã³ãœã³ã«ãã£ãŠå®£èšãããååïŒãã©ããªç ç²ãæã£ãŠãæåãé¿ãããã¯ãèšèªããã®ãããªéå
·ã§ããç¶ããããã«å¿
èŠã§ãã Haskellã¯ãåå°äœæè¡ãããææãéçºããŠããç 究ã»ã³ã¿ãŒã®ç 究宀ã«ããç¡è宀ã®ãããªãã®ã§ãã åãããšã¯ã²ã©ãäžäŸ¿ã§ãããæ¥åžžã®å®è·µã§ã¯è¡åã®èªç±ãå¶éããŸããããããã®äžäŸ¿ããªãã«ãå¶éã劥åããã«éµå®ããªããã°ãåŸã«ç£æ¥çºå±ã®åºç€ãšãªã埮åŠãªå¹æã芳å¯ããŠç 究ããããšã¯ã§ããŸããã åæã«ãç£æ¥çã§ã¯ãæãå¿
èŠãªéã ãç¡èæ§ãå¿
èŠã«ãªãããããã®å®éšã®çµæã¯ãã¬ãžã§ããã®åœ¢ã§ãã±ããã«è¡šç€ºãããŸãã æãéæ²³ãç 究ããã®ã¯ããããããçŽæ¥å©çãåŸãããšãæåŸ
ããããã§ã¯ãªãããããã®éå®çšçãªç©äœã®èŠæš¡ã§ãéåå¹æãçžå¯Ÿè«çå¹æã芳枬å¯èœã«ãªããç 究ãããããã«ãªã£ãããã§ãã ãã®ããããééã£ããç·ãèšç®ã®éå®çšçãªæ inessããããã€ãã®åæšè«ã¢ã«ãŽãªãºã ã®åæ§ãéåžžã«æ¥ãªå
¥åæ²ç·ã«ãããæçµçã«ã¯èããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã¹ããŒãã¢ããªã±ãŒã·ã§ã³ãç°¡åã«äœæã§ããŸããã ããããã¬ã³ãºãã¢ãããã³ã³ããããªã¢ã«è§£æãã¢ãã€ãã®åºç¯ãªäœ¿çšãèªåå®ç蚌æã®æ¹æ³ã宣èšåæ©èœããã±ãŒãžãããŒãžã£ãŒãç·åœ¢åããã³åŸå±åãå®éã®äžçã«è¿ã¥ããŠããŸãã ããã«ãããPythonãScalaãKotlinãFïŒãRustãªã©ã®èšèªã§ãç¡èç¶æ
ã®äœãã¢ããªã±ãŒã·ã§ã³ãèŠã€ãããŸãã ããããé¢æ°åããã°ã©ãã³ã°ã®ååãæããããã«ãããã®çŽ æŽãããèšèªã䜿çšããããšã¯ãããŸãããåŠçãç 究宀ã«é£ããŠè¡ããæããããããªäŸã§ã©ã®ããã«æ©èœãããã瀺ããŸãã倧ãããŠãããã«ããããéåžžã«é«éãªãã·ã³ã ã³ãŒããŒã¡ãŒã«ãŒãæ®åãããããã«é»åé¡åŸ®é¡ã«å
¥ããããšããè©Šã¿ã«å¯Ÿããä¿è·ã¯ããã¹ãŠã®ç ç²ãæã£ãŠåé¿ããããšã§ãã ãããŠãèšèªãããã¯ãŒã«ãªç«¶æäŒã§ã¯ãHaskellã¯åžžã«éåžžã®ããããŒãããå€ããŸãã
ãããããã®äººã¯åŒ±ããæªéãç§ã®äžã«äœãã§ããã®ã§ãä»äººã®åã§ãç§ã®å¥œããªèšèªããæ¯èŒãè©äŸ¡ãæè·ããŸãã ã ããããã®ã¢ã€ãã¢ãç§ã®ããã«åããã©ãããèŠããšããå¯äžã®ç®çã§ãã¢ãã€ãã«æ§æã«åºã¥ããŠç©ã¿éãããããã·ã³ã®ãšã¬ã¬ã³ããªå®è£
ãæžããåŸãç§ã¯å®è£
ãèŠäºã«ããããã²ã©ãéå¹ççã§ããããšã«æ°ã¥ããããšã«ããã«åæºããŸããïŒ ãŸãã§æ¬æ°ã§çå£ãªä»äºã«äœ¿ã£ãããPythonãJavaã®ä»®æ³ãã·ã³ãæäŸãããŠããã®ãšåãåžå Žã§ã¹ã¿ãã¯ããã·ã³ã販売ããããããããªãã®ã§ãã ãããããããæ°ã«ããŠãäŒè©±å
šäœãå§ãŸã£ãåè±ã«ã€ããŠã®èšäºã¯ãã®ãããªããããæ°åãäžããŸãïŒåè±ã®æ°çŸããªç§ãPythonã®ç§...ãããŠç§ã®çŸããã¢ãã€ãã¯1æéã§åãã¿ã¹ã¯ã«å¯ŸåŠã§ããŸããïŒ ç§ã¯æåããªããã°ãªããŸããïŒ ç§ã®é¡åŸ®é¡ã¯ãç 究æã®å»äžã«ããã³ãŒããŒã¡ãŒã«ãŒãšåãããããšã¹ãã¬ããœãéžé ããŸãïŒ ã¯ãªã¹ã¿ã«ãã¬ã¹ã¯åæ£ããŠå®å®ã«æã¡äžããããšãã§ããŸãïŒ
ããããããªãã¯ãããããæºåãã§ããŠããŸãããæ°åŠè
ã®å€©äœ¿ã¯ç§ã«å°ããŸããïŒ å®®æ®¿å»ºç¯ã®çŽåºŠãšéææ§ã¯ïŒ ããã°ã©ã ããä»ã®ãœãªã¥ãŒã·ã§ã³ãžã®æºååæ§ãæäŸããæè»æ§ãšæ¡åŒµæ§ïŒ æªéãšå€©äœ¿ã¯ã©ã¡ããé åºã§ãããç§ãç§ã«çããããŠããè³¢æãªéæåŸã¯ãç§ãã¡ãäž¡æ¹ã«åã£ãéãåããå¯èœãªéãããã«åŸãããšã瀺åããŸããã ãã ããåè
ãç¹å®ããããšãç®çãšããã®ã§ã¯ãªãããã¹èªäœãç¥ãããããã©ã®çšåºŠé²ãã§ãããã調ã¹ãæ°ããçµéšãåŸãããã«ã ãããŠãç§ã¯æé©åã®ç¡é§ãªæ²ãã¿ãšåã³ãç¥ã£ãŠããŸããã
å§ããåã«ãå¹æã®èŠ³ç¹ããã®èšèªã®æ¯èŒã¯ç¡æå³ã§ãããšä»ãå ããŸãã 翻蚳è
ïŒéèš³è
ãŸãã¯ã³ã³ãã€ã©ïŒããŸãã¯èšèªã䜿çšããããã°ã©ãã®ããã©ãŒãã³ã¹ãæ¯èŒããå¿
èŠããããŸãã æçµçã«ãCããã°ã©ã ãæéã§ãããšãã䞻匵ã¯ãããšãã°BASICã§å®å
šãªCã€ã³ã¿ããªã¿ãæžãããšã§ç°¡åã«è«ç Žã§ããŸãã ãã®ãããHaskellãšjavascriptãæ¯èŒããã®ã§ã¯ãªãã ghc
ã«ãã£ãŠã³ã³ãã€ã«ãããghc
ã«ãã£ãŠå®è¡ãããããã°ã©ã ãšãããšãã°ç¹å®ã®ãã©ãŠã¶ãŒã§å®è¡ãããããã°ã©ã ã®ããã©ãŒãã³ã¹ãæ¯èŒããŠããŸãã è±ã®çšèªã¯ãã¹ãŠãç©ã¿éããããæ©æ¢°ã«é¢ããåºæ¿çãªèšäºã«ç±æ¥ããŠããŸãã èšäºã«ä»éãããã¹ãŠã®Haskellã³ãŒãã¯ã ãªããžããªã§èª¿ã¹ãããšãã§ããŸã ã
å¿«é©å°åž¯ãé¢ãã
éå§äœçœ®ã¯ã EDSLã®åœ¢åŒã§ã®ã¢ãã€ãã«ã¹ã¿ãã¯ãã·ã³ã®å®è£
ã§ããããã¯ã2ããŒã¹ã®ããªããã£ããçµã¿åãããŠä»®æ³ã¹ã¿ãã¯ãã·ã³ã®ããã°ã©ã ãã¬ã³ããªã³ã°ã§ããå°ããªã·ã³ãã«ãªèšèªã§ãã 圌ã2çªç®ã®èšäºã«å
¥ã£ããããã«ã圌ã«monopig
ãšããååãmonopig
ãŸãã ã¹ã¿ãã¯ãã·ã³ã®èšèªã¯ãé£çµæäœãšç©ºã®æäœã1ã€ã®åäœãšããŠã¢ãã€ãã圢æãããšããäºå®ã«åºã¥ããŠããŸãã ãããã£ãŠã圌èªèº«ã¯æ©æ¢°ã®ç¶æ
ã®ã¢ãã€ãå€æã®åœ¢ã§æ§ç¯ãããŸããã ç¶æ
ã«ã¯ãã¹ã¿ãã¯ããã¯ãã«åœ¢åŒã®ã¡ã¢ãªïŒèŠçŽ ãžã®ã©ã³ãã ã¢ã¯ã»ã¹ãæäŸããæ§é ïŒãç·æ¥åæ¢ãã©ã°ãããã³ãããã°æ
å ±ãèç©ããããã®ã¢ãã€ãã«ããããªãå«ãŸããŸãã ãã®æ§é å
šäœããæäœããæäœãžã®å
éšæºååã®ãã§ãŒã³ã«æ²¿ã£ãŠéä¿¡ãããèšç®ããã»ã¹ãå®è¡ããŸãã ããã°ã©ã ã³ãŒãã®ååæ§é 㯠ãããã°ã©ã ã圢æããæ§é ããæ§ç¯ããããããããåŒæ°ãšã¡ã¢ãªã®æ°ã®èŠ³ç¹ããããã°ã©ã ã®èŠä»¶ãè¡šãä»ã®æçšãªæ§é ã«æºååå€æãããŸãã æ§ç¯ã®æçµæ®µéã¯ãã¯ã¬ã€ãºãªãŒã«ããŽãªã§ã®ã¢ãã€ãå€æã®äœæã§ãããããã«ãããä»»æã®ã¢ããã«èšç®ã浞ãããšãã§ããŸãã ãã®ããããã·ã³ã«ã¯å
¥åºåãšãããŸããªèšç®ã®æ©èœããããŸããã ãã®å®è£
ããå§ããŸãã 圌女ã®ã³ãŒãã¯ããã«ãããŸã ã
ãšã©ãã¹ããã¹ã®ãµããã®çŽ æŽãªå®è£
ã§ããã°ã©ã ã®æå¹æ§ããã¹ãããŸããããã¯ãã¡ã¢ãªïŒé
åïŒããŒããš1ã§æºãããçŽ æ°ããŒãã§è¡šããŸãã ã¢ã«ãŽãªãºã ã®æç¶ãã³ãŒããjavascript
ã§æäŸããŸãã
var memSize = 65536; var arr = []; for (var i = 0; i < memSize; i++) arr.push(0); function sieve() { var n = 2; while (n*n < memSize) { if (!arr[n]) { var k = n; while (k < memSize) { k+=n; arr[k] = 1; } } n++; } }
ã¢ã«ãŽãªãºã ã¯ããã«æé©åãããŸãã ãã§ã«æºããããŠããã¡ã¢ãªã»ã«ãæªçšããããšã¯ãããŸããã ç§ã®æ°åŠè
ã®å€©äœ¿ã¯ã PorosenokVM
ãããžã§ã¯ãã®äŸããã®æ¬åœã«çŽ æŽãªããŒãžã§ã³ã«ã¯åæããŸããã§ããããã®æé©åã«ã¯ã¹ã¿ãã¯èšèªã®5ã€ã®åœä»€ããå¿
èŠãªãããã§ãã ã¢ã«ãŽãªãºã ãmonopig
å€æãããæ¹æ³ã¯monopig
ã§ãã
sieve = push 2 <> while (dup <> dup <> mul <> push memSize <> lt) (dup <> get <> branch mempty fill <> inc) <> pop fill = dup <> dup <> add <> while (dup <> push memSize <> lt) (dup <> push 1 <> swap <> put <> exch <> add) <> pop
ãããŠã monopig
ãšåãåã䜿çšããŠããã®ã¢ã«ãŽãªãºã ã®åçã®å®è£
ãæ
£çšçãªHaskelläžã§ã©ã®ããã«æžãããšãã§ãããã以äžã«ç€ºããŸãã
sieve' :: Int -> Vector Int -> Vector Int sieve' km | k*k < memSize = sieve' (k+1) $ if m ! k == 0 then fill' k (2*k) m else m | otherwise = m fill' :: Int -> Int -> Vector Int -> Vector Int fill' knm | n < memSize = fill' k (n+k) $ m // [(n,1)] | otherwise = m
Data.Vector
ã¿ã€ããšãããæäœããããŒã«ã䜿çšããŸãããHaskellã§ã®æ¥åžžçãªäœæ¥ã«ã¯ããŸãäžè¬çã§ã¯ãããŸããã åŒm ! k
m ! k
ã¯ãã¯ãã«m
ã®k
çªç®ã®èŠçŽ ãè¿ãã m // [(n,1)]
-çªå·n
èŠçŽ ãm // [(n,1)]
èšå®ããŸããHaskellã§åããŠããŠããå©ããå¿
èŠãªãããããã«æžããŠããŸããã»ãŒæ¯æ¥ã å®éã®ãšãããæ©èœå®è£
ã§ã®ã©ã³ãã ã¢ã¯ã»ã¹ãåããæ§é ã¯éå¹ççã§ããããã®çç±ããæãããŠããŸããã
åè±ã«é¢ããèšäºã§æå®ããã競åæ¡ä»¶ã«åŸã£ãŠãã¢ã«ãŽãªãºã ã¯100åå®è¡ãããŸãã ç¹å®ã®ã³ã³ãã¥ãŒã¿ãŒãåé€ããããã«ãããã3ã€ã®ããã°ã©ã ã®å®è¡é床ãæ¯èŒããChromeã§å®è¡ãããjavascript
ããã°ã©ã ã®ããã©ãŒãã³ã¹ãåç
§ããŠã¿ãŸãããã

ãã©ãŒãã©ãŒ!!! monopig
ã¯monopig
ã¹ããŒããŠã³ããã ãã§ãªãããã€ãã£ãããŒãžã§ã³ã¯ããã»ã©è¯ããããŸããïŒ ãã¡ãããHaskellã¯ã¯ãŒã«ã§ããããã©ãŠã¶ã§å®è¡ãããŠããããã°ã©ã ã«å£ããŸãããïŒïŒ ã³ãŒããæããŠãããããã«ãããªãã¯ãã®ããã«çããããšã¯ã§ããŸãããHaskellãæäŸããå¿«é©ãŸãŒã³ãé¢ããæã§ãïŒ
æ lazãå
æãã
æ£ããããŸãããã ãããè¡ãã«ã¯ã -rtsopts
ãã©ã°ãmonopig
ããŠ-rtsopts
ããã°ã©ã ãã³ã³ãã€ã«ããå®è¡æã®çµ±èšã-rtsopts
ããšã©ãã¹ããã¹ã·ãŒãã1åå®è¡ããå¿
èŠããããã®ã確èªããŸãã
$ ghc -O -rtsopts ./Monopig4.hs [1 of 1] Compiling Main ( Monopig4.hs, Monopig4.o ) Linking Monopig4 ... $ ./Monopig4 -RTS -sstderr "Ok" 68,243,040,608 bytes allocated in the heap 6,471,530,040 bytes copied during GC 2,950,952 bytes maximum residency (30667 sample(s)) 42,264 bytes maximum slop 15 MB total memory in use (7 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 99408 colls, 0 par 2.758s 2.718s 0.0000s 0.0015s Gen 1 30667 colls, 0 par 57.654s 57.777s 0.0019s 0.0133s INIT time 0.000s ( 0.000s elapsed) MUT time 29.008s ( 29.111s elapsed) GC time 60.411s ( 60.495s elapsed) <-- ! EXIT time 0.000s ( 0.000s elapsed) Total time 89.423s ( 89.607s elapsed) %GC time 67.6% (67.5% elapsed) Alloc rate 2,352,591,525 bytes per MUT second Productivity 32.4% of total user, 32.4% of total elapsed
æåŸã®è¡ã¯ãããã°ã©ã ãçç£çãªã³ã³ãã¥ãŒãã£ã³ã°ã«åŸäºããã®ã¯3åã®1ã«éããªãã£ãããšã瀺ããŠããŸãã æ®ãã®æéãã¬ããŒãžã³ã¬ã¯ã¿ãŒã¯ã¡ã¢ãªããå®è¡ãããé
延èšç®ã®ããã«ã¯ãªãŒã³ã¢ãããããŸããã å°å
æã«æ ã¯è¯ããªããšäœåºŠãèšãããŸããïŒ ããã§ãHaskellã®äž»ãªæ©èœã¯ãæ°ååã®é
延ãã¯ãã«ããã³ã¹ã¿ãã¯å€æãäœæããããšããŠãç§ãã¡ã«æ害ãäžããŸããã
ãã®æç¹ã§æ°åŠã®å€©äœ¿ã¯æãæã¡äžããŠãã¢ãã³ãŸæäŒã®æ代以æ¥ãèšç®æŠç¥ãçµæã«åœ±é¿ãäžããªããšããå®çããããšããäºå®ã«ã€ããŠåãã§èªã£ãŠããŸããããã¯ãå¹çã®çç±ããèªç±ã«éžæã§ããããšãæå³ããŸãã èšç®ãå³å¯ã«å€æŽããããšã¯ãŸã£ããé£ãããããŸãã!
ã¹ã¿ãã¯ããã³ã¡ã¢ãªã®ã¿ã€ãã®å®£èšã§ããããã®ãã£ãŒã«ããå³å¯ã«ããŸãã
data VM a = VM { stack :: !Stack , status :: Maybe String , memory :: !Memory , journal :: !a }
ä»ã®ãã®ã¯å€æŽãããããã«çµæã確èªããŸãã
$ ./Monopig41 +RTS -sstderr "Ok" 68,244,819,008 bytes allocated in the heap 7,386,896 bytes copied during GC 528,088 bytes maximum residency (2 sample(s)) 25,248 bytes maximum slop 16 MB total memory in use (14 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 129923 colls, 0 par 0.666s 0.654s 0.0000s 0.0001s Gen 1 2 colls, 0 par 0.001s 0.001s 0.0006s 0.0007s INIT time 0.000s ( 0.000s elapsed) MUT time 13.029s ( 13.048s elapsed) GC time 0.667s ( 0.655s elapsed) EXIT time 0.001s ( 0.001s elapsed) Total time 13.700s ( 13.704s elapsed) %GC time 4.9% (4.8% elapsed) Alloc rate 5,238,049,412 bytes per MUT second Productivity 95.1% of total user, 95.1% of total elapsed
çç£æ§ã倧å¹
ã«åäžããŸããã ããŒã¿ã®äžå€æ§ã«ãããåèšã¡ã¢ãªã³ã¹ãã¯äŸç¶ãšããŠå°è±¡çã§ããããæãéèŠãªããšã¯ãããŒã¿ã®é
延ãå¶éããããšã§ãã¬ããŒãžã³ã¬ã¯ã¿ãŒãé
延ããæ©äŒããããäœæ¥ã®5ïŒ
ã ããæ®ã£ãŠããããšã§ãã è©äŸ¡ã«æ°ãããšã³ããªãå
¥åããŸãã

ããŠãå³å¯ãªèšç®ã«ãããHaskellã®ãã€ãã£ãã³ãŒãã®é床ã«è¿ã¥ããä»®æ³ãã·ã³ãªãã§ã¯æ¥ããããé
ããªããŸãã ããã¯ãäžå€ãã¯ãã«ã䜿çšãããªãŒããŒãããããã¹ã¿ãã¯ããããã·ã³ãç¶æããã³ã¹ãã倧å¹
ã«äžåãããšãæå³ããŸãã ããã¯ãã¡ã¢ãªã®äžå€æ§ã«å¥ããåããæãæ¥ãããšãæå³ããŸãã
人çãå€ãã
Data.Vector
åData.Vector
é©åã§ãããããã䜿çšããŠãã³ã³ãã¥ãŒãã£ã³ã°ããã»ã¹ã®çŽåºŠãç¶æããããã«ãã³ããŒã«å€ãã®æéãè²»ãããŸãã ãããData.Vector.Unpacked
ã¿ã€ãã«çœ®ãæãããšãå°ãªããšãæ§é äœã®ããã±ãŒãžã³ã°ã¯ââç¯çŽãããŸãããããã«ããç»åãæ ¹æ¬çã«å€ããããšã¯ãããŸããã æ£ãã解決çã¯ããã·ã³ã®ç¶æ
ããã¡ã¢ãªãåé€ããClaysleyã«ããŽãªã䜿çšããŠå€éšãã¯ãã«ãžã®ã¢ã¯ã»ã¹ãæäŸããããšã§ãã ããã«ãçŽç²ãªãã¯ãã«ãšãšãã«ãããããå¯å€ïŒå¯å€ïŒãã¯ãã«Data.Vector.Mutable
䜿çšã§ããŸãã
é©åãªã¢ãžã¥ãŒã«ãæ¥ç¶ããã¯ãªãŒã³ã§æ©èœçãªããã°ã©ã ã§å¯å€ããŒââã¿ãåŠçããæ¹æ³ãèããŸãã
import Control.Monad.Primitive import qualified Data.Vector.Unboxed as V import qualified Data.Vector.Unboxed.Mutable as M
ãããã®ããŒãã£ã¿ã€ãã¯ãçŽç²ãªå€§è¡ããéé¢ãããããšã«ãªã£ãŠããŸãã ãããã¯ã PrimMonad
ã¯ã©ã¹ã®ã¢ããïŒ ST
ãŸãã¯IO
å«ãïŒã«å«ãŸããŠãããã¯ãªãŒã³ããã°ã©ã ã¯ã貎éãªçŸç®çŽã«ã¯ãªã¹ã¿ã«é¢æ°åèšèªã§èšè¿°ãããã¢ã¯ã·ã§ã³ã®æ瀺ã泚ææ·±ãæ¿å
¥ããŸãã ãããã£ãŠããããã®æ±ããåç©ã®è¡åã¯å³å¯ã«æ£çµ±çãªã·ããªãªã«ãã£ãŠæ±ºå®ãããå±éºã§ã¯ãããŸããã ç§ãã¡ã®ãã·ã³ã®ãã¹ãŠã®ããã°ã©ã ãã¡ã¢ãªã䜿çšããããã§ã¯ãªãã®ã§ãã¢ãŒããã¯ãã£å
šäœãIO
ã¢ããã«æ²¡é ãããå¿
èŠã¯ãããŸããã monopig
èšèªã®ã¯ãªãŒã³ãªãµãã»ãããšãšãã«ãã¡ã¢ãªãžã®ã¢ã¯ã»ã¹ãæäŸãã4ã€ã®åœä»€ãäœæããŸãããããã®åœä»€ã®ã¿ãå±éºãªé åã«ã¢ã¯ã»ã¹ã§ããŸãã
ã¯ãªãŒã³ãã·ã³ã®çš®é¡ã¯çããªã£ãŠããŸãã
data VM a = VM { stack :: !Stack , status :: Maybe String , journal :: !a }
ããã°ã©ã ã®èšèšè
ãšããã°ã©ã èªäœã¯ãã®å€æŽã«ã»ãšãã©æ°ä»ããªãã§ããããããã®ã¿ã€ãã¯å€ãããŸãã ããã«ãã·ã°ããã£ãŒãç°¡çŽ åããããã«ãããã€ãã®ã¿ã€ãã®å矩èªãå®çŸ©ããããšã¯çã«ããªã£ãŠããŸãã
type Memory m = M.MVector (PrimState m) Int type Logger ma = Memory m -> Code -> VM a -> m (VM a) type Program' ma = Logger ma -> Memory m -> Program ma
ã³ã³ã¹ãã©ã¯ã¿ã«ã¯ãã¡ã¢ãªã¢ã¯ã»ã¹ãè¡šãå¥ã®åŒæ°ããããŸãã å®è¡è
ãç¹ã«èšç®ãã°ãä¿æããŠãã人ã¯ãå€æ°ãã¯ãã«ã®ç¶æ
ãå°ããå¿
èŠãããããã倧å¹
ã«å€ãããŸãã å®å
šãªã³ãŒãã¯ãªããžããªã§ç¢ºèªããã³èª¿æ»ã§ããŸãããããã§æãèå³æ·±ãã®ã¯ãã¡ã¢ãªãæäœããããã®åºæ¬ã³ã³ããŒãã³ãã®å®è£
ã§ããããããã©ã®ããã«è¡ããããã瀺ããŸãã
geti :: PrimMonad m => Int -> Program' ma geti i = programM (GETI i) $ \mem -> \s -> if (0 <= i && i < memSize) then \vm -> do x <- M.unsafeRead mem i setStack (x:s) vm else err "index out of range" puti :: PrimMonad m => Int -> Program' ma puti i = programM (PUTI i) $ \mem -> \case (x:s) -> if (0 <= i && i < memSize) then \vm -> do M.unsafeWrite mem ix setStack s vm else err "index out of range" _ -> err "expected an element" get :: PrimMonad m => Program' ma get = programM (GET) $ \m -> \case (i:s) -> \vm -> do x <- M.read mi setStack (x:s) vm _ -> err "expected an element" put :: PrimMonad m => Program' ma put = programM (PUT) $ \m -> \case (i:x:s) -> \vm -> M.write mix >> setStack s vm _ -> err "expected two elemets"
puti
ããã³geti
ã€ã³ããã¯ã¹ã¯ããã°ã©ã äœæã®æ®µéã§æ¢ç¥ã§ããã誀ã£ãå€ãäºåã«é€å»ã§ããããããªããã£ãã€ã¶ãŒããŒã¢ã³ã¯ããã«ã¡ã¢ãªå
ã®èš±å®¹ã€ã³ããã¯ã¹å€ã®ãã§ãã¯ãããå°ãç¯çŽããããšãææ¡ããŸããã put
ããã³get
ã³ãã³ãã®åçã«å®çŸ©ãããã€ã³ããã¯ã¹ã¯ã»ãã¥ãªãã£ãä¿èšŒãããæ°åŠè
ã®ãšã³ãžã§ã«ã¯ããããžã®å±éºãªåŒã³åºããèš±å¯ããŸããã§ããã
ã¡ã¢ãªãåå¥ã®åŒæ°ã«å
¥ããããšã«é¢ãããã®ãã¹ãŠã®éšãã¯è€éã«æããŸãã ããããããŒã¿ã¯å Žæã«ãã£ãŠå€æŽãããããšãéåžžã«æ確ã«ç€ºããŠããŸããããŒã¿ã¯å€éšã«ããå¿
èŠããããŸãã ãã¶é
é人ãç¡èæ€æ»å®€ã«é£ããŠè¡ãããšããŠããããšãæãåºãããŠãã ããã çŽç²ãªæ©èœã¯äœããã¹ãããç¥ã£ãŠããŸããããããã®ãªããžã§ã¯ãã¯æ±ºããŠäžæµã®åžæ°ã«ãªãããšã¯ãªããå®éšå®€ã§ãã¶ãæºåãã䟡å€ã¯ãããŸããã
ãããã®å€æŽã§è³Œå
¥ãããã®ã確èªããŸãããã
$ ./Monopig5 +RTS -sstderr "Ok" 9,169,192,928 bytes allocated in the heap 2,006,680 bytes copied during GC 529,608 bytes maximum residency (2 sample(s)) 25,248 bytes maximum slop 2 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 17693 colls, 0 par 0.094s 0.093s 0.0000s 0.0001s Gen 1 2 colls, 0 par 0.000s 0.000s 0.0002s 0.0003s INIT time 0.000s ( 0.000s elapsed) MUT time 7.228s ( 7.232s elapsed) GC time 0.094s ( 0.093s elapsed) EXIT time 0.000s ( 0.000s elapsed) Total time 7.325s ( 7.326s elapsed) %GC time 1.3% (1.3% elapsed) Alloc rate 1,268,570,828 bytes per MUT second Productivity 98.7% of total user, 98.7% of total elapsed
ããã¯ãã§ã«é²è¡äžã§ãïŒ ã¡ã¢ãªäœ¿çšéã¯8åã«åæžãããããã°ã©ã ã®å®è¡é床ã¯180åã«å¢å ããã¬ããŒãžã³ã¬ã¯ã¿ãŒã¯ã»ãŒå®å
šã«äœæ¥ãªãã§æ®ããŸããã

溶液ã¯monopig stãã«èŠããŸããã mutã ãããã¯js
ã®ãã€ãã£ããœãªã¥ãŒã·ã§ã³ããã10åé
ãã§ãããHaskellã®ãã€ãã£ããœãªã¥ãŒã·ã§ã³ãšã¯ç°ãªããå¯å€ãã¯ãã«ã䜿çšããŠããŸãã 圌ã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
fill' :: Int -> Int -> Memory IO -> IO (Memory IO) fill' knm | n > memSize-k = return m | otherwise = M.unsafeWrite mn 1 >> fill' k (n+k) m sieve' :: Int -> Memory IO -> IO (Memory IO) sieve' km | k*k < memSize = do x <- M.unsafeRead mk if x == 0 then fill' k (2*k) m >>= sieve' (k+1) else sieve' (k+1) m | otherwise = return m
次ã®ããã«å§ãŸããŸã
main = do m <- M.replicate memSize 0 stimes 100 (sieve' 2 m >> return ()) print "Ok"
ãããŠä»ãHaskellã¯ã€ãã«åœŒãããã¡ãã®èšèªã§ã¯ãªãããšã瀺ããŠããŸãã ããªãã¯ãããè³¢ã䜿çšããå¿
èŠããããŸãã ãšããã§ãäžèšã®ã³ãŒãã¯ãã¿ã€ãIO ()
ãããã°ã©ã ã®é 次å®è¡(>>)
ã®æäœã§ã»ãã°ã«ãŒãã圢æãã stimes
ã®å©ããåããŠãã¹ãåé¡ã®èšç®ã100åç¹°ãè¿ãããšããäºå®ã䜿çšããŠããŸãã
ããã§ãé¢æ°é
åããããªã«å«ããªã®ã¯ãªããããããŠãªã圌ããšäžç·ã«äœæ¥ããã®ã誰ãèŠããŠããªãã®ã¯æããã§ãã
ã³ãã³ãã®äžéšãç¹å¥ãªãŸãŒã³ã«å
¥ãããšãååã®åæ³æ§ã«çåãçããŸã ããã°ã©ã ã çµå±ã®ãšãããã³ãŒããåæã«çŽç²ãªããã°ã©ã ãšã¢ãããªãã®ã«å€ããããšã¯ã§ããŸãããããã«ãããåã·ã¹ãã ã¯ããããããšãã§ããŸããã ãã ããåã¯ã©ã¹ã¯ãã®ååãååšããã®ã«ååãªæè»æ§ãåããŠããŸãã æºåååå ãã®ããã°ã©ã ã¯çŸåšãèšèªã®ããŸããŸãªãµãã»ããã®ããã€ãã®æºååã«åå²ãããŠããŸãã ãããã©ã®ããã«è¡ããããã¯ãããã°ã©ã ã®[ã³ãŒã]ïŒïŒå
šäœã§ç¢ºèªã§ããŸãã
æ¢ãŸããªãã§
äžèŠãªé¢æ°åŒã³åºãããªããã {-# INLINE #-}
ãã©ã°ãã䜿çšããŠã³ãŒããçŽæ¥åã蟌ããšãããã°ã©ã ã®çç£æ§ããããã«å€ãããŸãã ãã®ã¡ãœããã¯ãååž°é¢æ°ã«ã¯é©ããŠããŸããããåºæ¬çãªã³ã³ããŒãã³ãããã³ã»ãã¿ãŒé¢æ°ã«ã¯é©ããŠããŸãã ãã¹ãããã°ã©ã ã®å®è¡æéãããã«25ïŒ
ççž®ããŸãïŒ Monopig51.hsãåç
§ïŒã

次ã®åŠ¥åœãªã¹ãããã¯ããã°ããŒã«ãäžèŠãªå Žåã¯åé€ããããšã§ãã ããã°ã©ã ãè¡šãå
éšæºååã®åœ¢æã®æ®µéã§ãèµ·åæã«æ±ºå®ããå€éšåŒæ°ã䜿çšããŸãã ã¹ããŒãã³ã³ã¹ãã©ã¯ã¿ãŒprogram
ããã³programM
ã¯ãåŒæ°ãã¬ãŒããªãå¯èœæ§ãããããšãèŠåã§ããŸãã ãã®å Žåãã³ã³ããŒã¿ã³ãŒãã«ã¯äœåãªãã®ã¯å«ãŸããŠããŸãããæ©èœãšãã·ã³ã®ã¹ããŒã¿ã¹ã®ç¢ºèªã®ã¿ã§ãã
program code f = programM code (const f) programM code f (Just logger) mem = Program . ([code],) . ActionM $ \vm -> case status vm of Nothing -> logger mem code =<< f mem (stack vm) vm _ -> return vm programM code f _ mem = Program . ([code],) . ActionM $ \vm -> case status vm of Nothing -> f mem (stack vm) vm _ -> return vm
çŸåšãå®è¡äžã®é¢æ°ã¯ã none
ã¹ã¿ãã䜿çšãnone
ã Maybe (Logger ma)
ã¿ã€ãMaybe (Logger ma)
ã䜿çšããŠããã®ã³ã°ã®æç¡ãæ瀺çã«ç€ºãå¿
èŠããããŸãã ãã®ã³ã°ããããã©ããã«ããããããããã°ã©ã ã³ã³ããŒãã³ãã¯å®è¡ã®åã«ãæåŸã®ç¬éããèŠã€ããã®ã§ããªããããæ©èœããã®ã§ããïŒ ããã°ã©ã ã®æ§æãäœæãã段éã§ãäžèŠãªã³ãŒããçž«ãä»ããŸãããïŒ Haskellã¯æ zyãªèšèªã§ãããããã§ç§ãã¡ã®æã«æž¡ããŸãã æçµã³ãŒããç¹å®ã®ã¿ã¹ã¯çšã«æé©åãããã®ã¯ãå®è¡åã§ãã ãã®æé©åã«ãããããã°ã©ã ã®å®è¡æéãããã«40ïŒ
ççž®ãããŸããïŒ Monopig52.hsãåç
§ïŒã

ããã§ãã¢ãã€ãã®åè±ãå éããäœæ¥ãå®äºããŸãã 圌ã¯ãã§ã«å€©äœ¿ãšæªéã®äž¡æ¹ãèœã¡çãããšãã§ããããã«ååã«éãèµ°ã£ãŠããŸãã ãã¡ãããããã¯Cã§ã¯ãªãããŸã ã¯ãªãŒã³ãªã¹ããã¹ã¿ãã¯ãšããŠäœ¿çšããŠããŸããããããé
åã«çœ®ãæãããšãã³ãŒãã培åºçã«ã·ã£ãã«ã«ãªããåºæ¬çãªã³ãã³ãã®å®çŸ©ã§ãšã¬ã¬ã³ããªãã³ãã¬ãŒãã®äœ¿çšãæåŠãããŸãã æå°éã®å€æŽã§ãäž»ã«ã¿ã€ãã®ã¬ãã«ã§å¯ŸåŠãããã£ãã®ã§ãã
ãã®ã³ã°ã«ã¯ããã€ãã®åé¡ãæ®ã£ãŠããŸãã åçŽãªã¹ãããæ°ã®ã«ãŠã³ããã¹ã¿ãã¯ã®äœ¿çšã¯ããŸãæ©èœããŸãïŒãã°ãã£ãŒã«ããå³å¯ã«ããŸããïŒãããããã®ãã¢ãªã³ã°ã¯æ¢ã«ã¡ã¢ãªãæ¶è²»ãå§ããŠããã®ã§ã seq
ã䜿çšããŠããã¯ã«æ©ãŸããªããã°ãªããŸããã ããããæåã®æ°çŸã®ã¿ã¹ã¯ããããã°ã§ããå Žåã誰ã140åã®ã¹ããããèšé²ããŸããïŒ ãããã£ãŠãå éã®ããã«å éã«æéãè²»ããããšã¯ãããŸããã
èšç®ãæé©åããæ¹æ³ã®1ã€ãšããŠãåè±ã«é¢ããèšäºã«ãããè¿œå ããã ãã§ãããã¬ãŒã¹ã®æäŸïŒã³ãŒãã®ç·åœ¢ã»ã¯ã·ã§ã³ã®å²ãåœãŠãã¡ã€ã³ã³ãã³ããã£ã¹ããããµã€ã¯ã«ïŒ switch
ãããã¯ïŒããã€ãã¹ããŠèšç®ãå®è¡ã§ãããã¬ãŒã¹ ã ãã®å Žåãããã°ã©ã ã³ã³ããŒãã³ãã®ã¢ãã€ãæ§æã¯ãEDSã³ã³ããŒãã³ãããã®ããã°ã©ã ã®åœ¢æäžããŸãã¯fromCode
æºååãfromCode
ãããšãã«ããã®ãããªãã¬ãŒã¹ãäœæããŸãã ãã®æé©åæ¹æ³ã¯ãããã°ã建èšã«ãã£ãŠç¡æã§æäŸãããŸãã
Haskellãšã³ã·ã¹ãã ã«ã¯ã Conduits
ãPipes
ã¹ããªãŒã ãªã©ã®Conduits
é«éãªãœãªã¥ãŒã·ã§ã³ãæ°å€ããããåªããString
眮æãblaze-htmlãªã©ã®è»œå¿«ãªXMLã¯ãªãšãŒã¿ãŒããããŸãattoparsec
ããŒãµãŒã¯ãLLïŒâïŒææ³ã®çµã¿åããåæã®æšæºã§ãã ããã¯ãã¹ãŠéåžžã®æäœã«å¿
èŠã§ãã ãããããããã®æ±ºå®ã«ã€ãªããç 究ãããã«å¿
èŠã§ãã Haskellã¯ãããŸã§ãçŸåšããäžè¬ã®äººã
ãå¿
èŠãšããªãç¹å®ã®èŠä»¶ãæºããç 究ããŒã«ã§ãã ç§ã¯ã«ã ãã£ãã«ã§ãMi-4ããªã³ãã¿ãŒã®ãšãŒã¹ãè°è«ã§ãããç®±ãéãã空äžã«ã¶ãäžãã£ãŠããéã«è»èŒªã§çéžè£
眮ãæŒãæ¹æ³ãèŠãŸããã ããã¯å®è¡ã§ããŸãããã¯ãŒã«ã§ããå¿
èŠã§ã¯ãããŸããã
ããããããã«ãããããããããã¯ã¯ãŒã«ã§ã!!