git.iko.soy/typeable/elm-ui
on master help sign in
330 lines 8.3 kB history raw
1module Suite exposing (main)
3import Benchmark exposing (Benchmark)
4import Benchmark.Runner exposing (BenchmarkProgram, program)
5import Dict
6import Element exposing (..)
7import Element.Background as Background
8import Element.Font as Font
9import Html
10import Html.Attributes
11import Internal.Flag as Flag
12import Internal.Model as Internal
13import Json.Encode
14import Set
17dict : Benchmark
18dict =
19 let
20 dest =
21 Dict.singleton "a" 1
22 in
23 Benchmark.describe "dictionary"
24 [ Benchmark.benchmark "get" (\_ -> Dict.get "a" dest)
25 , Benchmark.benchmark "insert" (\_ -> Dict.insert "b" 2 dest)
26 ]
29main : BenchmarkProgram
30main =
31 program <|
32 Benchmark.describe "sample"
33 [ --dict
34 -- , deduplications
35 -- renderPipeline
36 gatheringAttributes
38 -- flagOperations
39 ]
42flagOperations =
43 Benchmark.describe "Flag Operations"
44 [ Benchmark.benchmark "check if present" <|
45 \_ ->
46 Flag.present Flag.height Flag.none
47 , Benchmark.benchmark "add to flagt" <|
48 \_ ->
49 Flag.add Flag.height Flag.none
50 ]
53gatheringAttributes =
54 Benchmark.describe "Gathering Attributes"
55 [ Benchmark.benchmark "existing - gatherAttrRecursive" <|
56 \_ ->
57 Internal.gatherAttrRecursive
58 (Internal.contextClasses Internal.AsEl)
59 Internal.Generic
60 Flag.none
61 Internal.Untransformed
62 []
63 []
64 Internal.NoNearbyChildren
65 [ Element.width Element.shrink
66 , Element.height Element.shrink
67 ]
68 , Benchmark.benchmark "Simple list filterMap" <|
69 \_ ->
70 List.filterMap
71 identity
72 [ Just "thing"
73 , Just "other width"
74 ]
75 , Benchmark.benchmark "Simple list map" <|
76 \_ ->
77 List.map
78 identity
79 [ Just "thing"
80 , Just "other width"
81 ]
82 , Benchmark.benchmark "Foldl base speed" <|
83 \_ ->
84 List.foldl
85 (::)
86 [ Just "thing"
87 , Just "other width"
88 ]
89 , Benchmark.benchmark "Recursive" <|
90 \_ ->
91 recurse
92 (::)
93 [ Just "thing"
94 , Just "other width"
95 ]
96 , Benchmark.benchmark "foldl - new record each iteration" <|
97 \_ ->
98 List.foldl flipFoldl
99 { attributes = "class"
100 , styles = []
101 , node = "Node"
102 , children = Nothing
103 , has = Flag.none
104 }
105 -- we reverse first because we have to for the attr api.
106 (List.reverse
107 [ Just "thing"
108 , Just "other width"
109 ]
110 )
111 , Benchmark.benchmark "foldl - update" <|
112 \_ ->
113 List.foldl flipFoldlUpdate
114 { attributes = "class"
115 , styles = []
116 , node = "Node"
117 , children = Nothing
118 , has = Flag.none
119 }
120 -- we reverse first because we have to for the attr api.
121 (List.reverse
122 [ Just "thing"
123 , Just "other width"
124 ]
125 )
126 , Benchmark.benchmark "String Concatenation" <|
127 \_ ->
128 "This"
129 ++ "this"
130 ++ "this"
131 ++ "this"
132 ++ "this"
133 ++ "this"
134 ++ "this"
135 ++ "this"
136 , Benchmark.benchmark "List String Concatenation" <|
137 \_ ->
138 String.concat
139 [ "This"
140 , "this"
141 , "this"
142 , "this"
143 , "this"
144 , "this"
145 , "this"
146 , "this"
147 ]
148 ]
151flipFoldl result found =
152 { attributes = "class" ++ found.attributes
153 , styles = Just 1 :: found.styles
154 , node = found.node
155 , children = Nothing
156 , has = Flag.add Flag.height found.has
157 }
160flipFoldlUpdate result found =
161 { found
162 | attributes = "class" ++ found.attributes
163 , styles = Just 1 :: found.styles
164 , has = Flag.add Flag.height found.has
165 }
168recurse fn ls =
169 case ls of
170 [] ->
171 []
173 fst :: remain ->
174 fn fst (recurse fn remain)
177deduplications =
178 Benchmark.describe "deduplications"
179 [ Benchmark.benchmark "fold - dedup, String concat"
180 (\_ ->
181 String.join ":" (foldDedup largeList)
182 )
183 , Benchmark.benchmark "fold - dedup"
184 (\_ ->
185 foldDedup largeList
186 )
187 , Benchmark.benchmark "fold - dedup - Int"
188 (\_ ->
189 foldDedup largeListInt
190 )
191 , Benchmark.benchmark "Json encode"
192 (\_ ->
193 Json.Encode.object largeListJson
194 )
195 ]
198foldDedup list =
199 let
200 dedup ( name, val ) ( cache, ls ) =
201 if Set.member name cache then
202 ( cache, ls )
204 else
205 ( Set.insert name cache, val :: ls )
206 in
207 List.foldl dedup ( Set.empty, [] ) list
208 |> Tuple.second
211largeListInt =
212 List.range 1 10000
213 |> List.map
214 (\i ->
215 let
216 wrappingI =
217 modBy 50 i
218 in
219 ( wrappingI, "elem-" ++ String.fromInt wrappingI )
220 )
223largeList =
224 List.range 1 10000
225 |> List.map
226 (\i ->
227 let
228 wrappingI =
229 modBy 50 i
230 in
231 ( "elem-" ++ String.fromInt wrappingI, "elem-" ++ String.fromInt wrappingI )
232 )
235largeListJson =
236 List.range 1 10000
237 |> List.map
238 (\i ->
239 let
240 wrappingI =
241 modBy 50 i
242 in
243 ( "elem-" ++ String.fromInt wrappingI, Json.Encode.string ("elem-" ++ String.fromInt wrappingI) )
244 )
247renderPipeline =
248 [ Benchmark.benchmark "build 2000 elements"
249 (\_ ->
250 elements 0 twoThousand
251 )
252 , Benchmark.benchmark "build 2000 html"
253 (\_ ->
254 html 0 twoThousand
255 )
256 ]
259twoThousand =
260 List.range 0 2000
263elements i count =
264 Element.layout []
265 (Element.column [ spacing 8, centerX ]
266 (List.map (viewEl i) count)
267 )
270viewEl selectedIndex index =
271 el
272 [ Background.color
273 (if selectedIndex == index then
274 pink
276 else
277 white
278 )
279 , Font.color
280 (if selectedIndex /= index then
281 pink
283 else
284 white
285 )
286 , padding 24
287 , width (px 500)
288 , height (px 70)
289 ]
290 (if selectedIndex == index then
291 text "selected"
293 else
294 text "Hello!"
295 )
298white =
299 rgb 1 1 1
302pink =
303 rgb255 240 0 245
306html i count =
307 Html.div []
308 [ Html.div []
309 (List.map (viewHtmlElement i) count)
310 ]
313viewHtmlElement selectedIndex index =
314 Html.div
315 [ Html.Attributes.class
316 (if selectedIndex == index then
317 "white"
319 else
320 "pink"
321 )
322 ]
323 [ Html.div []
324 [ if selectedIndex == index then
325 Html.text "selected"
327 else
328 Html.text "Hello!"
329 ]
330 ]