Created
January 2, 2023 18:11
-
-
Save joakin/3f3c861b0e388f90a20ff27493a2ffd4 to your computer and use it in GitHub Desktop.
Elm benchmarking the best way to encode things to JSON and a few other things
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
module Main exposing (suite) | |
import Array exposing (Array) | |
import Benchmark as B exposing (..) | |
import Benchmark.Runner exposing (..) | |
import Dict | |
import Json.Encode as E | |
object = | |
{ fn = "rect", x = 12, y = 52, width = 123, height = 138, color = "blue" } | |
objectList100 = | |
List.range 0 100 |> List.map (always object) | |
objectArray100 = | |
Array.initialize 100 (\_ -> object) | |
encodeOneAsObject obj = | |
E.object | |
[ ( "fn", E.string obj.fn ) | |
, ( "x", E.int obj.x ) | |
, ( "y", E.int obj.y ) | |
, ( "width", E.int obj.width ) | |
, ( "height", E.int obj.height ) | |
, ( "color", E.string obj.color ) | |
] | |
encodeOneAsList obj = | |
E.list identity [ E.string obj.fn, E.int obj.x, E.int obj.y, E.int obj.width, E.int obj.height, E.string obj.color ] | |
encodeOneAsString obj = | |
obj.fn | |
++ "|" | |
++ String.fromInt obj.x | |
++ "|" | |
++ String.fromInt obj.y | |
++ "|" | |
++ String.fromInt obj.width | |
++ "|" | |
++ String.fromInt obj.height | |
++ "|" | |
++ obj.color | |
listAsString : (a -> String) -> List a -> String | |
listAsString fn list = | |
List.foldl (\v acc -> acc ++ fn v) "" list | |
arrayAsString : (a -> String) -> Array a -> String | |
arrayAsString fn list = | |
Array.foldl (\v acc -> acc ++ fn v) "" list | |
suite : Benchmark | |
suite = | |
describe "All the things" | |
[ -- describe "JS interop" | |
-- [ encodeOne | |
-- , encode100 | |
-- ] , | |
-- describe "Updating objects/dict like structures" | |
-- [ updateRecord | |
-- , updateRecordFullObject | |
-- , updateDict | |
-- ], | |
describe "Iterating over 1000 item collections, and making lists out of them" | |
[ mapList | |
, mapArray | |
, mapDict | |
, foldrList | |
, foldrArray | |
, foldrDict | |
] | |
] | |
encodeOne = | |
describe "Encoding one object" | |
[ benchmark "Json.Encode.object" | |
(\_ -> encodeOneAsObject object) | |
, benchmark "Json.Encode.list" | |
(\_ -> encodeOneAsList object) | |
, benchmark "Json.Encode.string" | |
(\_ -> encodeOneAsString object) | |
] | |
encode100 = | |
describe "Encoding 100 objects" | |
[ benchmark "E.list encodeOneAsObject" | |
(\_ -> E.list encodeOneAsObject objectList100) | |
, benchmark "E.array encodeOneAsObject" | |
(\_ -> E.array encodeOneAsObject objectArray100) | |
, benchmark "E.list encodeOneAsList" | |
(\_ -> E.list encodeOneAsList objectList100) | |
, benchmark "E.array encodeOneAsList" | |
(\_ -> E.array encodeOneAsList objectArray100) | |
, benchmark "listAsString encodeOneAsString" | |
(\_ -> listAsString encodeOneAsString objectList100) | |
, benchmark "listAsString encodeOneAsString" | |
(\_ -> arrayAsString encodeOneAsString objectArray100) | |
] | |
updateRecord = | |
benchmark "Update record with native syntax" | |
(\_ -> | |
let | |
surname = | |
emptyRecord.surname | |
in | |
{ emptyRecord | surname = surname ++ "wat" } | |
) | |
updateRecordFullObject = | |
benchmark "Update record with full object syntax" | |
(\_ -> | |
let | |
surname = | |
emptyRecord.surname | |
in | |
{ name = emptyRecord.name, surname = surname ++ "wat" } | |
) | |
updateDict = | |
benchmark "Update dict insert" | |
(\_ -> | |
let | |
surname = | |
Dict.get "surname" dict | |
in | |
Maybe.map (\s -> Dict.insert "surname" (s ++ "wat") dict) surname | |
) | |
mapList = | |
let | |
xs = | |
List.range 0 1000 |> List.map (always 0) | |
in | |
benchmark "List.map" | |
(\_ -> | |
xs |> List.map (always 1) | |
) | |
mapArray = | |
let | |
xs = | |
List.range 0 1000 |> List.map (always 0) |> Array.fromList | |
in | |
benchmark "Array.map" | |
(\_ -> | |
xs |> Array.map (always 1) | |
) | |
mapDict = | |
let | |
xs = | |
List.range 0 1000 |> List.map (\i -> ( i, 0 )) |> Dict.fromList | |
in | |
benchmark "Dict.map" | |
(\_ -> | |
xs |> Dict.map (\k x -> 1) | |
) | |
foldrList = | |
let | |
xs = | |
List.range 0 1000 |> List.map (always 0) | |
in | |
benchmark "List.foldr to make a list" | |
(\_ -> | |
List.foldr (\x acc -> x :: acc) [] xs | |
) | |
foldrArray = | |
let | |
xs = | |
List.range 0 1000 |> List.map (always 0) |> Array.fromList | |
in | |
benchmark "Array.foldr to make a list" | |
(\_ -> | |
Array.foldr (\x acc -> x :: acc) [] xs | |
) | |
foldrDict = | |
let | |
xs = | |
List.range 0 1000 |> List.map (\i -> ( i, 0 )) |> Dict.fromList | |
in | |
benchmark "Dict.foldr to make a list" | |
(\_ -> | |
Dict.foldr (\k x acc -> x :: acc) [] xs | |
) | |
emptyRecord = | |
{ f0 = "" | |
, f1 = "" | |
, f2 = "" | |
, f3 = "" | |
, f4 = "" | |
, f5 = "" | |
, f6 = "" | |
, f7 = "" | |
, f8 = "" | |
, f9 = "" | |
, f10 = "" | |
, f11 = "" | |
, f12 = "" | |
, f13 = "" | |
, f14 = "" | |
, f15 = "" | |
, name = "Banana" | |
, surname = "Phone" | |
} | |
dict = | |
Dict.empty | |
|> Dict.insert "f0" "" | |
|> Dict.insert "f1" "" | |
|> Dict.insert "f2" "" | |
|> Dict.insert "f3" "" | |
|> Dict.insert "f4" "" | |
|> Dict.insert "f5" "" | |
|> Dict.insert "f6" "" | |
|> Dict.insert "f7" "" | |
|> Dict.insert "f8" "" | |
|> Dict.insert "f9" "" | |
|> Dict.insert "f10" "" | |
|> Dict.insert "f11" "" | |
|> Dict.insert "f12" "" | |
|> Dict.insert "f13" "" | |
|> Dict.insert "f14" "" | |
|> Dict.insert "f15" "" | |
|> Dict.insert "name" "Banana" | |
|> Dict.insert "surname" "Phone" | |
main : BenchmarkProgram | |
main = | |
program suite |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment