Created
February 22, 2018 12:02
-
-
Save minoki/9610b1c9113cf3787e221fcce7265f5b to your computer and use it in GitHub Desktop.
関数内ローカル変数に IORef を使うな
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE MagicHash #-} | |
module Main where | |
import Data.IORef | |
import Control.Monad (forM_) | |
import System.Environment (getArgs) | |
import Control.Monad.State.Class | |
import qualified Control.Monad.State.Strict as StateStrict | |
import qualified Control.Monad.State.Lazy as StateLazy | |
import Control.Monad.Writer.Strict as WriterStrict | |
import GHC.Prim | |
import GHC.Types | |
{-# NOINLINE someCalculationWithRec #-} | |
someCalculationWithRec :: IO Int | |
someCalculationWithRec = return (loop 0 0) | |
where loop i acc | i > 10000 * 10000 = acc | |
| otherwise = loop (i+1) (acc + (i `rem` 3)) | |
{-# NOINLINE someCalculationWithIORef #-} | |
someCalculationWithIORef :: IO Int | |
someCalculationWithIORef = do | |
sumRef <- newIORef (0 :: Int) | |
forM_ [0..10000 * 10000] $ \i -> do | |
modifyIORef' sumRef (+ (i `rem` 3)) | |
readIORef sumRef | |
{-# NOINLINE someCalculationWithIORefLazy #-} | |
someCalculationWithIORefLazy :: IO Int | |
someCalculationWithIORefLazy = do | |
sumRef <- newIORef (0 :: Int) | |
forM_ [0..10000 * 10000] $ \i -> do | |
modifyIORef sumRef (+ (i `rem` 3)) | |
readIORef sumRef | |
{-# NOINLINE someCalculationWithIORefRW #-} | |
someCalculationWithIORefRW :: IO Int | |
someCalculationWithIORefRW = do | |
sumRef <- newIORef (0 :: Int) | |
forM_ [0..10000 * 10000] $ \i -> do | |
s <- readIORef sumRef | |
writeIORef sumRef $! s + (i `rem` 3) | |
readIORef sumRef | |
{-# NOINLINE someCalculationWithState #-} | |
someCalculationWithState :: IO Int | |
someCalculationWithState = flip StateStrict.evalStateT 0 $ do | |
forM_ [0..10000 * 10000] $ \i -> do | |
modify' (+ (i `rem` 3)) | |
get | |
{-# NOINLINE someCalculationWithStateLazy #-} | |
someCalculationWithStateLazy :: IO Int | |
someCalculationWithStateLazy = flip StateLazy.evalStateT 0 $ do | |
forM_ [0..10000 * 10000] $ \i -> do | |
modify' (+ (i `rem` 3)) | |
get | |
{-# NOINLINE someCalculationWithWriter #-} | |
someCalculationWithWriter :: IO Int | |
someCalculationWithWriter = return $ getSum $ WriterStrict.execWriter $ do | |
forM_ [0..10000 * 10000] $ \i -> do | |
tell (Sum (i `rem` 3)) | |
{-# NOINLINE someCalculationWithUnboxed #-} | |
someCalculationWithUnboxed :: IO Int | |
someCalculationWithUnboxed = return (I# (loop 0# 0#)) | |
where loop i# acc# = case i# ># 100000000# of | |
1# -> acc# | |
_ -> loop (i# +# 1#) (acc# +# (i# `remInt#` 3#)) | |
main :: IO () | |
main = do | |
args <- getArgs | |
case args of | |
"Rec":_ -> someCalculationWithRec >>= print | |
"IORef":_ -> someCalculationWithIORef >>= print | |
"IORefLazy":_ -> someCalculationWithIORefLazy >>= print | |
"IORefRW":_ -> someCalculationWithIORefRW >>= print | |
"State":_ -> someCalculationWithState >>= print | |
"StateLazy":_ -> someCalculationWithStateLazy >>= print | |
"Writer":_ -> someCalculationWithWriter >>= print | |
"Unboxed":_ -> someCalculationWithUnboxed >>= print | |
_ -> putStrLn "argument: one of Rec, IORef, IORefLazy, IORefRW, State, StateLazy, Writer, Unboxed" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: ioref-test | |
version: 0.1.0.0 | |
license: BSD3 | |
author: "ARATA Mizuki" | |
copyright: "2018 ARATA Mizuki" | |
dependencies: | |
- base >= 4.7 && < 5 | |
- mtl | |
- ghc-prim | |
executables: | |
ioref-test-exe: | |
main: Main.hs | |
ghc-options: | |
- -threaded | |
- -ddump-simpl | |
- -ddump-asm | |
- -ddump-to-file | |
- -Wall |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <memory> | |
int someCalculation() | |
{ | |
int sum = 0; | |
for (int i = 0; i <= 10000 * 10000; ++i) { | |
sum += i % 3; | |
} | |
return sum; | |
} | |
int someCalculationWithPtr() | |
{ | |
std::unique_ptr<int> sumRef{new int()}; | |
for (int i = 0; i <= 10000 * 10000; ++i) { | |
*sumRef += i % 3; | |
} | |
return *sumRef; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
if (argc > 1 && strcmp(argv[1], "ptr") == 0) { | |
printf("%d\n", someCalculationWithPtr()); | |
} else { | |
printf("%d\n", someCalculation()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment