-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.hs
88 lines (78 loc) · 2.65 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module Main
( main,
)
where
import Control.Monad (forM, replicateM_)
import Data.Attoparsec.ByteString.Lazy (Result (Done, Fail))
import Data.ByteString.Lazy (isPrefixOf)
import qualified Data.ByteString.Lazy as BS (readFile)
import Data.List (isSuffixOf)
import Data.Oktade.Classfile (parseClassfile, unparseClassfile)
import System.Clock (Clock (Monotonic), diffTimeSpec, getTime, toNanoSecs)
import System.Directory (doesFileExist, getCurrentDirectory, listDirectory)
import System.FilePath ((</>))
main :: IO ()
main = do
intro
paths <- cfrTestsPaths
warmup 10 paths
benchmark 200 paths
cfrTestsPaths :: IO [FilePath]
cfrTestsPaths = do
currentDir <- getCurrentDirectory
let testDir = currentDir </> "testsuite" </> "resources" </> "cfr-tests"
walk [] testDir
where
walk :: [FilePath] -> FilePath -> IO [FilePath]
walk fs p = do
isFile <- doesFileExist p
if isFile
then if ".class" `isSuffixOf` p then return $ p : fs else return fs
else walkDir fs p
walkDir :: [FilePath] -> FilePath -> IO [FilePath]
walkDir fs p =
do
content <- listDirectory p
concat <$> forM ((p </>) <$> content) (walk fs)
intro :: IO ()
intro = do
putStrLn $
"\nOne iteration of this benchmark parses and unparses all classfiles in the"
++ " cfr-tests project sequentially."
putStrLn
"Only file reading and parsing will be measured.\n"
warmup :: Int -> [FilePath] -> IO ()
warmup c ps = do
putStrLn $ "Warmup, running " ++ show c ++ " iterations..."
run c ps
benchmark :: Int -> [FilePath] -> IO ()
benchmark c ps = do
putStrLn $ "Benchmark, running " ++ show c ++ " iterations..."
nsDuration <- timeNanoSecs $ run c ps
let msDuration = nsDuration `div` 1000000
let avgMsDuration = nsDuration `div` fromIntegral c `div` 1000000
evaluation msDuration avgMsDuration
timeNanoSecs :: IO () -> IO Integer
timeNanoSecs a = do
start <- getTime Monotonic
a
end <- getTime Monotonic
return $ toNanoSecs (diffTimeSpec start end)
run :: Int -> [FilePath] -> IO ()
run c ps = replicateM_ c $ parseClassfiles ps
parseClassfiles :: [FilePath] -> IO ()
parseClassfiles = mapM_ parse
where
parse p = do
classfile <- BS.readFile p
case parseClassfile classfile of
Fail {} -> putStrLn $ "Warning: Failed parsing " ++ show p
(Done _ result) -> do
if unparseClassfile result `isPrefixOf` classfile
then return ()
else putStrLn $ "Warning: Failed homomorphism " ++ show p
evaluation :: Integer -> Integer -> IO ()
evaluation ms avgMs =
putStrLn $
"Benchmark took " ++ show ms ++ "ms (" ++ show avgMs
++ "ms per iteration in average).\n"