diff options
Diffstat (limited to 'test/bench.hs')
-rw-r--r-- | test/bench.hs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/test/bench.hs b/test/bench.hs new file mode 100644 index 0000000..9952ec2 --- /dev/null +++ b/test/bench.hs | |||
@@ -0,0 +1,82 @@ | |||
1 | {-# LANGUAGE ForeignFunctionInterface #-} | ||
2 | import qualified Data.Attoparsec.Text as Atto | ||
3 | import qualified Data.ByteString.Char8 as S | ||
4 | import qualified Data.ByteString.Lazy.Char8 as L | ||
5 | import Data.List as List | ||
6 | import Data.Either | ||
7 | import Data.ByteString.Unsafe | ||
8 | import Data.Text | ||
9 | import Data.Text.Encoding | ||
10 | import Data.Word | ||
11 | import Foreign.Ptr | ||
12 | import System.IO.Unsafe | ||
13 | import qualified Data.Vector as V | ||
14 | import Control.Monad.State ( State, execState, gets, modify ) | ||
15 | import qualified Data.IntMap as IntMap | ||
16 | |||
17 | import Codec.Wavefront.Lexer ( lexer ) | ||
18 | import Codec.Wavefront.Object ( WavefrontOBJ, ctxtToWavefrontOBJ, objLocations ) | ||
19 | import Codec.Wavefront.Token ( tokenize ) | ||
20 | |||
21 | import qualified Graphics.WaveFront.Parse as Parse | ||
22 | import qualified Graphics.WaveFront.Parse.Common as Parse | ||
23 | |||
24 | import Wavefront | ||
25 | |||
26 | import Criterion.Main | ||
27 | import Weigh -- WARNING: weigh is incompatible with profiling. It reports much more allocations with profiling turned on. | ||
28 | |||
29 | foreign import ccall "&cube_obj" cube_ptr :: Ptr Word8 | ||
30 | cube_obj_len :: Int | ||
31 | cube_obj_len = 840 | ||
32 | |||
33 | cube_obj :: L.ByteString | ||
34 | cube_obj = L.fromChunks . pure . unsafePerformIO $ do | ||
35 | unsafePackCStringFinalizer cube_ptr cube_obj_len (return ()) | ||
36 | {-# NOINLINE cube_obj #-} | ||
37 | |||
38 | cube_objT :: Text | ||
39 | cube_objT = decodeASCII $ L.toStrict cube_obj | ||
40 | {-# NOINLINE cube_objT #-} | ||
41 | |||
42 | countVerticesSabadie :: Text -> Int | ||
43 | countVerticesSabadie ts = V.length vs | ||
44 | where | ||
45 | obj = sabadie ts | ||
46 | vs = either (const V.empty) objLocations obj | ||
47 | |||
48 | countVerticesSundqvist :: Text -> Int | ||
49 | countVerticesSundqvist ts = List.length vs | ||
50 | where | ||
51 | obj = sundqvist ts | ||
52 | vs = either (const []) (List.filter isOBJVertex) obj | ||
53 | isOBJVertex (Parse.OBJVertex {}) = True | ||
54 | isOBJVertex _ = False | ||
55 | |||
56 | countVerticesCrayne :: L.ByteString -> Int | ||
57 | countVerticesCrayne bs = execState (parseOBJ builder (ObjConfig IntMap.empty) bs) 0 | ||
58 | where | ||
59 | builder = nullBuilder | ||
60 | { vertex = \_ -> modify succ | ||
61 | } | ||
62 | |||
63 | sabadie :: Text -> Either String WavefrontOBJ | ||
64 | sabadie = fmap (ctxtToWavefrontOBJ . lexer) . tokenize | ||
65 | |||
66 | sundqvist :: Text -> Either String (Parse.OBJ Double Text Integer []) | ||
67 | sundqvist = Atto.parseOnly (Parse.wholeFile Parse.obj) | ||
68 | |||
69 | main :: IO () | ||
70 | main = do | ||
71 | print $ countVerticesSabadie cube_objT | ||
72 | print $ countVerticesSundqvist cube_objT | ||
73 | print $ countVerticesCrayne cube_obj | ||
74 | putStrLn $ "---- Benchmarking" | ||
75 | defaultMain [ | ||
76 | bgroup "count vertices" | ||
77 | [ bench "crayne" $ whnf countVerticesCrayne cube_obj | ||
78 | , bench "sabadie" $ whnf countVerticesSabadie cube_objT | ||
79 | , bench "sundqvist" $ whnf countVerticesSundqvist cube_objT | ||
80 | ] | ||
81 | ] | ||
82 | return () | ||