summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-06-12 19:39:29 -0400
committerJoe Crayne <joe@jerkface.net>2019-06-12 19:39:29 -0400
commit6ee08be31b394b54f77c243a3691864e9e229f43 (patch)
treed0c6e2109096b2dca508fae139f253933d645c53
parent550c43c8491e2b6a2873caf8e9c032b69e56e03f (diff)
benchmarks
-rw-r--r--src/Wavefront.hs33
-rw-r--r--test/bench.hs82
-rw-r--r--test/cube.c54
-rw-r--r--wavefront-obj.cabal6
4 files changed, 175 insertions, 0 deletions
diff --git a/src/Wavefront.hs b/src/Wavefront.hs
index 66d6cdb..9e42779 100644
--- a/src/Wavefront.hs
+++ b/src/Wavefront.hs
@@ -42,6 +42,39 @@ data ObjBuilder m = ObjBuilder
42 , badToken :: L.ByteString -> m () 42 , badToken :: L.ByteString -> m ()
43 } 43 }
44 44
45nullBuilder :: Applicative m => ObjBuilder m
46nullBuilder = ObjBuilder
47 { vertex = \vs -> pure ()
48 , vertexT = \vs -> pure ()
49 , vertexN = \vs -> pure ()
50 , vertexP = \vs -> pure ()
51 , face = \is -> pure ()
52 , cstype = \isRat typ -> pure ()
53 , curv2 = \is -> pure ()
54 , curv = \u0 v0 is -> pure ()
55 , parm = \isU is -> pure ()
56 , specialPoints = \is -> pure ()
57 , endFreeForm = pure ()
58 , ctech = \approx -> pure ()
59 , stech = \approx -> pure ()
60 , deg = \is -> pure ()
61 , surf = \u0 u1 v0 v1 ts -> pure ()
62 , trim = \ss -> pure ()
63 , hole = \ss -> pure ()
64 , specialCurves = \ss -> pure ()
65 , equivalentCurves = \ccs -> pure ()
66 , groups = \gs -> pure ()
67 , smoothingGroup = \sg -> pure ()
68 , mergingGroup = \mg δ -> pure ()
69 , usemtl = \mtl -> pure ()
70 , deprecated_cdc = \is -> pure ()
71 , deprecated_bzp = \is -> pure ()
72 , mtllib = \fns -> pure ()
73 , objectName = \obn -> pure ()
74 , badToken = \bs -> pure ()
75 }
76
77
45data CurveSamplingSpec 78data CurveSamplingSpec
46 -- ctech cparm 79 -- ctech cparm
47 = UniformSubdivision 80 = UniformSubdivision
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 #-}
2import qualified Data.Attoparsec.Text as Atto
3import qualified Data.ByteString.Char8 as S
4import qualified Data.ByteString.Lazy.Char8 as L
5import Data.List as List
6import Data.Either
7import Data.ByteString.Unsafe
8import Data.Text
9import Data.Text.Encoding
10import Data.Word
11import Foreign.Ptr
12import System.IO.Unsafe
13import qualified Data.Vector as V
14import Control.Monad.State ( State, execState, gets, modify )
15import qualified Data.IntMap as IntMap
16
17import Codec.Wavefront.Lexer ( lexer )
18import Codec.Wavefront.Object ( WavefrontOBJ, ctxtToWavefrontOBJ, objLocations )
19import Codec.Wavefront.Token ( tokenize )
20
21import qualified Graphics.WaveFront.Parse as Parse
22import qualified Graphics.WaveFront.Parse.Common as Parse
23
24import Wavefront
25
26import Criterion.Main
27import Weigh -- WARNING: weigh is incompatible with profiling. It reports much more allocations with profiling turned on.
28
29foreign import ccall "&cube_obj" cube_ptr :: Ptr Word8
30cube_obj_len :: Int
31cube_obj_len = 840
32
33cube_obj :: L.ByteString
34cube_obj = L.fromChunks . pure . unsafePerformIO $ do
35 unsafePackCStringFinalizer cube_ptr cube_obj_len (return ())
36{-# NOINLINE cube_obj #-}
37
38cube_objT :: Text
39cube_objT = decodeASCII $ L.toStrict cube_obj
40{-# NOINLINE cube_objT #-}
41
42countVerticesSabadie :: Text -> Int
43countVerticesSabadie ts = V.length vs
44 where
45 obj = sabadie ts
46 vs = either (const V.empty) objLocations obj
47
48countVerticesSundqvist :: Text -> Int
49countVerticesSundqvist 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
56countVerticesCrayne :: L.ByteString -> Int
57countVerticesCrayne bs = execState (parseOBJ builder (ObjConfig IntMap.empty) bs) 0
58 where
59 builder = nullBuilder
60 { vertex = \_ -> modify succ
61 }
62
63sabadie :: Text -> Either String WavefrontOBJ
64sabadie = fmap (ctxtToWavefrontOBJ . lexer) . tokenize
65
66sundqvist :: Text -> Either String (Parse.OBJ Double Text Integer [])
67sundqvist = Atto.parseOnly (Parse.wholeFile Parse.obj)
68
69main :: IO ()
70main = 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 ()
diff --git a/test/cube.c b/test/cube.c
new file mode 100644
index 0000000..952f32e
--- /dev/null
+++ b/test/cube.c
@@ -0,0 +1,54 @@
1
2unsigned char cube_obj[] =
3 " \n"
4 " \n"
5 // For now, sabadie parser has bug and cannot handle leading comments.
6 // "# cube.obj\n"
7 // "#\n"
8 "\n"
9 "o cube\n"
10 "mtllib cube.mtl\n"
11 "\n"
12 "v -0.500000 -0.500000 0.500000\n"
13 "v 0.500000 -0.500000 0.500000\n"
14 "v -0.500000 0.500000 0.500000\n"
15 "v 0.500000 0.500000 0.500000\n"
16 "v -0.500000 0.500000 -0.500000\n"
17 "v 0.500000 0.500000 -0.500000\n"
18 "v -0.500000 -0.500000 -0.500000\n"
19 "v 0.500000 -0.500000 -0.500000\n"
20 "\n"
21 "vt 0.000000 0.000000\n"
22 "vt 1.000000 0.000000\n"
23 "vt 0.000000 1.000000\n"
24 "vt 1.000000 1.000000\n"
25 "\n"
26 "vn 0.000000 0.000000 1.000000\n"
27 "vn 0.000000 1.000000 0.000000\n"
28 "vn 0.000000 0.000000 -1.000000\n"
29 "vn 0.000000 -1.000000 0.000000\n"
30 "vn 1.000000 0.000000 0.000000\n"
31 "vn -1.000000 0.000000 0.000000\n"
32 "\n"
33 "g cube\n"
34 "usemtl material0\n"
35 "s 1\n"
36 "f 1/1/1 2/2/1 3/3/1\n"
37 "f 3/3/1 2/2/1 4/4/1\n"
38 "s 2\n"
39 "f 3/1/2 4/2/2 5/3/2\n"
40 "f 5/3/2 4/2/2 6/4/2\n"
41 "s 3\n"
42 "f 5/4/3 6/3/3 7/2/3\n"
43 "f 7/2/3 6/3/3 8/1/3\n"
44 "s 4\n"
45 "f 7/1/4 8/2/4 1/3/4\n"
46 "f 1/3/4 8/2/4 2/4/4\n"
47 "s 5\n"
48 "f 2/1/5 8/2/5 4/3/5\n"
49 "f 4/3/5 8/2/5 6/4/5\n"
50 "s 6\n"
51 "f 7/1/6 1/2/6 5/3/6\n"
52 "f 5/3/6 1/2/6 3/4/6\n";
53
54unsigned int cube_obj_len = 840;
diff --git a/wavefront-obj.cabal b/wavefront-obj.cabal
index 612d6f5..a1087df 100644
--- a/wavefront-obj.cabal
+++ b/wavefront-obj.cabal
@@ -92,3 +92,9 @@ library
92 92
93 hs-source-dirs: src 93 hs-source-dirs: src
94 default-language: Haskell2010 94 default-language: Haskell2010
95
96executable bench
97 main-is: test/bench.hs
98 C-sources: test/cube.c
99 ghc-options: -Wall -rtsopts
100 build-depends: base, bytestring, attoparsec, text, vector, transformers, mtl, containers, wavefront-obj, criterion, weigh