2022-12-24

Map to Struct and Struct to Map Golang Benchmark 2022 Edition

Sometimes we want to convert from map to struct or struct to map (dictionary in other language), or even struct to struct. There's some library that can help us doing this, for example structs, mapstructure, copier, or smapping. We could also utilize serialization and deserialization libraries to do this. With caveats, that some serialization format (eg. JSON) doesn't allow integer larger than 2^53 for example.

Here's benchmark that I run this morning:

map to structtotalns/opB/opallocs/op
M2S_GoccyGoJson_MarshalUnmarshal-326,661,932517803
M2S_JsonIteratorGo_MarshalUnmarshal-324,892,6117241968
M2S_VmihailencoMspackV5_MarhsalUnmarshal-324,572,5977411885
M2S_FxamackerCbor_MarshalUnmarshal-324,418,5587991208
M2S_SurrealdbCork_EncodeDecode-323,080,2821,0801,2176
M2S_GopkgInMgoV2Bson_MarshalUnmarshal-323,227,9051,09223213
M2S_ShamatonMsgpackV2_MarshalUnmarshal-323,062,6771,16195615
M2S_MitchellhMapstructure_Decode-322,487,4281,39572018
M2S_MongoDriverBson_MarshalUnmarshal-322,477,9831,45941414
M2S_KokizzuJson5b_MarshalUnmarshal-321,987,2401,71163216
M2S_EncodingJson_MarshalUnmarshal-322,056,9441,78060016
M2S_EtNikBinngo_MarshalUnmarshal-321,985,5951,85742539
M2S_PquernaFfjson_MarshalUnmarshal-321,739,9681,98660916
M2S_UngorjiGocodec_BincEncodeDecode-321,401,4532,5824,34023
M2S_UngorjiGoCodec_CborEncodeDecode-321,304,8282,6364,34023
M2S_PelletierGoTomlV2_MarshalUnmarshal-321,284,0372,7871,60027
M2S_UngorjiGocodec_SimpleEncodeDecode-321,295,9262,8104,34023
M2S_UngorjiGocodec_JsonEncodeDecode-321,000,0003,0284,95625
M2S_IchibanTnetstrings_MarshalUnmarshal-32749,9475,0569,32948
M2S_BurntSushiToml_EncodeUnmarshal-32425,3358,0657,95871
M2S_HjsonHjsonGoV4_MarshalUnmarshal-32355,78410,8703,93678
M2S_GopkgInYamlV3_MarshalUnmarshal-32271,19013,52414,11280
M2S_DONUTSLz4Msgpack_MarshalUnmarshal-32240,61915,4981,26416
M2S_GoccyGoYaml_MarshalUnmarshal-32214,77616,1927,821214
M2S_GhodssYaml_MarshalUnmarshal-32156,41223,34721,378161
M2S_NaoinaToml_MarshalUnmarshal-3257,60758,331398,54477





struct to maptotalns/opB/opallocs/op
S2M_MitchellhMapstructure_Decode-325,055,40271653612
S2M_GoccyGoJson_MarshalUnmarshal-324,660,22474752212
S2M_JsonIteratorGo_MarshalUnmarshal-324,283,26283550514
S2M_VmihailencoMspackV5_MarhsalUnmarshal-324,009,86390860712
S2M_FxamackerCbor_MarshalUnmarshal-323,562,3521,02345211
S2M_ShamatonMsgpackV2_MarshalUnmarshal-323,180,0101,08955615
S2M_GopkgInMgoV2Bson_MarshalUnmarshal-323,047,3961,14552815
S2M_SurrealdbCork_EncodeDecode-322,976,3281,1961,61112
S2M_EncodingJson_MarshalUnmarshal-321,914,1651,78268818
S2M_PquernaFfjson_MarshalUnmarshal-321,911,9501,84569718
S2M_EtNikBinngo_MarshalUnmarshal-321,948,8021,85976845
S2M_KokizzuJson5b_MarshalUnmarshal-321,888,7741,88496020
S2M_MongoDriverBson_MarshalUnmarshal-321,857,6491,99575918
S2M_PelletierGoTomlV2_MarshalUnmarshal-321,244,0122,8641,80031
S2M_UngorjiGocodec_BincEncodeDecode-321,000,0003,2344,88834
S2M_UngorjiGoCodec_CborEncodeDecode-32989,6713,3584,88834
S2M_UngorjiGocodec_SimpleEncodeDecode-321,000,0003,4004,88834
S2M_UngorjiGocodec_JsonEncodeDecode-32912,5123,6395,50436
S2M_IchibanTnetstrings_MarshalUnmarshal-32776,7964,7449,56146
S2M_BurntSushiToml_EncodeUnmarshal-32447,2168,5388,23173
S2M_HjsonHjsonGoV4_MarshalUnmarshal-32389,4769,4163,86866
S2M_GopkgInYamlV3_MarshalUnmarshal-32315,93913,33814,40081
S2M_DONUTSLz4Msgpack_MarshalUnmarshal-32242,33014,29874416
S2M_GoccyGoYaml_MarshalUnmarshal-32230,04214,9197,580202
S2M_GhodssYaml_MarshalUnmarshal-32151,02322,68221,441161
S2M_NaoinaToml_MarshalUnmarshal-3260,91652,047398,11280





struct to structtotalns/opB/opallocs/op
S2S_GoccyGoJson_MarshalUnmarshal-3212,046,4973171124
S2S_ShamatonMsgpackV2_MarshalUnmarshal-327,897,4884581486
S2S_JsonIteratorGo_MarshalUnmarshal-327,853,592494926
S2S_FxamackerCbor_MarshalUnmarshal-327,038,808511805
S2S_GopkgInMgoV2Bson_MarshalUnmarshal-325,105,3437151449
S2S_VmihailencoMspackV5_MarhsalUnmarshal-324,549,7008182136
S2S_MongoDriverBson_MarshalUnmarshal-323,560,9461,0193218
S2S_EncodingJson_MarshalUnmarshal-322,731,0511,3133049
S2S_PquernaFfjson_MarshalUnmarshal-322,734,3571,3303049
S2S_KokizzuJson5b_MarshalUnmarshal-322,594,7281,3435049
S2S_SurrealdbCork_EncodeDecode-322,555,7451,3971,2417
S2S_EtNikBinngo_MarshalUnmarshal-321,995,4681,84040041
S2S_PelletierGoTomlV2_MarshalUnmarshal-321,460,6832,4591,44023
S2S_UngorjiGocodec_SimpleEncodeDecode-321,205,6482,9194,36424
S2S_UngorjiGoCodec_CborEncodeDecode-321,290,7342,9204,36424
S2S_UngorjiGocodec_BincEncodeDecode-321,207,3273,0074,36424
S2S_UngorjiGocodec_JsonEncodeDecode-321,000,0003,2234,98026
S2S_IchibanTnetstrings_MarshalUnmarshal-32722,4934,9509,28947
S2S_BurntSushiToml_EncodeUnmarshal-32398,3668,4587,91872
S2S_HjsonHjsonGoV4_MarshalUnmarshal-32304,36911,1894,57879
S2S_DONUTSLz4Msgpack_MarshalUnmarshal-32282,50512,2152377
S2S_GopkgInYamlV3_MarshalUnmarshal-32279,33212,54114,01676
S2S_GoccyGoYaml_MarshalUnmarshal-32211,95215,5427,982208
S2S_GhodssYaml_MarshalUnmarshal-32160,66023,14821,073154
S2S_NaoinaToml_MarshalUnmarshal-3264,46859,672399,06583

The repository and the always updated result is here, feel free to add your own serialization/deserialization library. As we can see, goccy-gojson is the fastest among all, too bad if you store int64 larger than 2^53 it give wrong result. So it's better to use second best and all rounder vmihailenco-msgpack, or for specific use case struct to map/struct is mapstructure.

Here's the top ranking:

Ser/Deser M2S S2M S2S
GoccyGoJson 1 2 2
JsonIteratorGo 2 3 4
MitchellhMapstructure 8 1 1
VmihailencoMspackV5 3 4 7
FxamackerCbor 4 5 5
ShamatonMsgpackV2 7 6 3
SurrealdbCork 5 8 12


2022-09-08

Getting started with InfluxDB

Today we're gonna learn about InfluxDB, a time series database that already been a standard for open source metric storage, a part of TICK stack (telegraf -- a metric collector like datadog-agent/fluentd, influx -- the database, chronograf -- visualizer like grafana, kapacitor -- an alert manager like prometheus alert-manager also for ETL). To install influx use this steps from this link (there's also docker). What's the cons of influx compared to other solution? Datadog is (very very) expensive, Prometheus seems too kube-oriented, Influx open source doesn't support HA and clustering, that's why I would rather use Clickhouse for time series / log collection (as data sink) and aggregate those logs as metrics (materialized view) and copy periodically to faster database like Tarantool. Influx have 2 query syntax, one is SQL-like called InfluxQL and other one Javascript+FP-like called Flux (it has |> pipe like most FP). Here's the example of docker and the query language:

docker run -d -e INFLUXDB_ADMIN_USER:user1 -e INFLUXDB_ADMIN_PASSWORD:pass1 --name influxdb1 influxdb

docker exec -it influxdb1 influx -host 127.0.0.1 -port 8086 -username user1 -password pass1

show databases
create database db1
use db1

-- show all tables (=measurements)

show measurements

-- tag/index always string, field can be float, int, bool, etc

insert into table1,tag1=a,tag2=b field1=1,field2=2

-- if not set, default time is in nanosecond of insert time

select * from "table1"
select * from table1 where tag1='a'

-- describe columns from all table:

show tag keys
show field keys from "table1"

-- select distinct tag from table1
show tag values from "table1" with key in ("tag1")

-- automatically delete after N days, default 0 = never delete
-- shard by N hours, default 168 hours (a week)
show retention policies

-- like partition in other database
show shards
show shard groups

I guess that's it what you need to know to get started with InfluxDB. If you're looking one that comparable with Clickhouse, you can check TDEngine or TiFlash.

2022-07-28

Techempower Framework Benchmark Round 21

 The result for Techempower framework benchmark round 21 is out, as usual the most important benchmark is the update and multi query benchmark:

The top rankers are Rust, JS (cheating), Java, C++, C#, PHP, C, Scala, Kotlin, and Go. For multiple queries:


Top rankers are Rust, Java, JS (cheating), Scala, Kotlin, C++, C#, and Go. These benchmark shows how efficient their database driver (which mostly the biggest bottleneck), and how much overhead the framework of each language (including serialization, alloc/GC, async-I/O, etc).

For memory usage and CPU utilization you can check here https://ajdust.github.io/tfbvis/?testrun=Citrine_started2022-06-30_edd8ab2e-018b-4041-92ce-03e5317d35ea&testtype=update&round=false