1 /++
2 Compares formats for your data.
3 +/
4 module mir.ion.benchmark;
5 
6 import mir.serde;
7 
8 ///
9 struct Report
10 {
11     import core.time: Duration;
12 
13     ///
14     size_t json_input_size;
15     ///
16     size_t json_minimized_size;
17     ///
18     size_t msgpack_size;
19     ///
20     size_t ion_size;
21 
22 @serdeProxy!string:
23 
24     /// Avg duration per call
25     Duration json_to_ion;
26     /// Avg duration per call
27     Duration ion_to_ion;
28     /// Avg duration per call
29     Duration ion_to_json;
30     /// Avg duration per call
31     Duration ion_to_msgpack;
32     /// Avg duration per call
33     Duration msgpack_to_ion;
34     /// Avg duration per call
35     Duration ion_parsgin;
36     /// Avg duration per call
37     Duration ion_writing;
38     /// Avg duration per call for JSON
39     Duration memcpy;
40 }
41 
42 ///
43 Report benchmarkData(string json, uint count)
44 {
45     import mir.algebraic_alias.json;
46     import mir.appender: scopedBuffer;
47     import mir.ion.conv;
48     import mir.ion.stream;
49     import mir.deser.ion: deserializeIon;
50 
51     auto jsonBuffer = scopedBuffer!char;
52     auto ionBuffer = scopedBuffer!ubyte;
53     auto binaryBuffer = scopedBuffer!ubyte;
54 
55     import std.datetime.stopwatch: benchmark;
56     json.json2ion(ionBuffer);
57     auto data = ionBuffer.data.deserializeIon!JsonAlgebraic;
58     auto memory = jsonBuffer.prepare(json.length);
59 
60     auto res = count.benchmark!(
61         () { // JSON -> Ion
62             ionBuffer.shrinkTo(0);
63             json.json2ion(ionBuffer);
64         },
65         () { // Ion -> Ion
66             import mir.ser.ion: serializeIon;
67             binaryBuffer.shrinkTo(0);
68             serializeIon(binaryBuffer, ionBuffer.data.IonValueStream);
69         },
70         () { // Ion -> JSON
71             import mir.ser.json: serializeJson;
72             jsonBuffer.shrinkTo(0);
73             serializeJson(jsonBuffer, ionBuffer.data.IonValueStream);
74         },
75         () { // Ion -> Msgpack
76             import mir.ser.msgpack: serializeMsgpack;
77             binaryBuffer.shrinkTo(0);
78             serializeMsgpack(binaryBuffer, ionBuffer.data.IonValueStream);
79         },
80         () { // Msgpack -> Ion
81             ionBuffer.shrinkTo(0);
82             binaryBuffer.data.msgpack2ion(ionBuffer);
83         },
84         () { // Data -> Ion
85             import mir.ser.ion: serializeIon;
86             ionBuffer.shrinkTo(0);
87             serializeIon(ionBuffer, data);
88         },
89         () { // memcpy
90             import core.stdc.string: memcpy;
91             memcpy(memory.ptr, json.ptr, json.length);
92         },
93     );
94 
95     Report report;
96 
97     report.json_to_ion = res[0] / count;
98     report.ion_to_ion = res[1] / count;
99     report.ion_to_json = res[2] / count;
100     report.ion_to_msgpack = res[3] / count;
101     report.msgpack_to_ion = res[4] / count;
102     report.ion_writing = res[5] / count;
103     report.ion_parsgin = report.ion_to_ion - report.ion_writing;
104     report.memcpy = res[6] / count;
105 
106     report.json_input_size = json.length;
107     report.json_minimized_size = jsonBuffer.data.length;
108     report.msgpack_size = binaryBuffer.data.length;
109     report.ion_size = ionBuffer.data.length;
110 
111     return report;
112 }