Skip to content

Instantly share code, notes, and snippets.

@joakin
Created January 2, 2023 18:11
Show Gist options
  • Save joakin/3f3c861b0e388f90a20ff27493a2ffd4 to your computer and use it in GitHub Desktop.
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
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