ssrjson-benchmark 0.0.3__cp312-cp312-win_amd64.whl → 0.0.5__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ssrjson-benchmark might be problematic. Click here for more details.

@@ -1,676 +0,0 @@
1
- import importlib
2
- import io
3
- import sys
4
- import os
5
- import gc
6
- import json
7
- from collections import defaultdict
8
- from typing import Any, Callable
9
- from typing import List
10
- import io
11
- import time
12
- import platform
13
- import re
14
- import pathlib
15
- import math
16
- from ssrjson_benchmark import _ssrjson_benchmark
17
- import matplotlib.pyplot as plt
18
- import matplotlib as mpl
19
-
20
- import orjson
21
- import ujson
22
- import ssrjson
23
-
24
-
25
- mpl.use("Agg")
26
- mpl.rcParams["svg.fonttype"] = "none"
27
-
28
-
29
- try:
30
- from svglib.fonts import FontMap
31
-
32
- font_map = FontMap()
33
- font_map.register_default_fonts()
34
- # workaround for matplotlib using 700 to represent bold font, but svg2rlg using 700 as normal.
35
- font_map.register_font("Helvetica", weight="700", rlgFontName="Helvetica-Bold")
36
- except ImportError:
37
- pass
38
-
39
- CUR_FILE = os.path.abspath(__file__)
40
- CUR_DIR = os.path.dirname(CUR_FILE)
41
- CWD = os.getcwd()
42
- _NS_IN_ONE_S = 1000000000
43
-
44
- PDF_HEADING_FONT = "Helvetica-Bold"
45
- PDF_TEXT_FONT = "Courier"
46
-
47
- # baseline is the first one.
48
- LIBRARIES_COLORS = {
49
- "json": "#74c476",
50
- "ujson": "#c994c7",
51
- "orjson": "#2c7fb8",
52
- "ssrjson": "#fd8d3c",
53
- }
54
- LIBRARIES: dict[str, dict[str, Callable[[str | bytes], Any]]] = {
55
- "dumps": {
56
- "json.dumps": json.dumps,
57
- "ujson.dumps": ujson.dumps,
58
- "orjson.dumps+decode": lambda x: orjson.dumps(x).decode("utf-8"),
59
- "ssrjson.dumps": ssrjson.dumps,
60
- },
61
- "dumps(indented2)": {
62
- "json.dumps": lambda x: json.dumps(x, indent=2),
63
- "ujson.dumps+decode": lambda x: ujson.dumps(x, indent=2),
64
- "orjson.dumps": lambda x: orjson.dumps(x, option=orjson.OPT_INDENT_2),
65
- "ssrjson.dumps": lambda x: ssrjson.dumps(x, indent=2),
66
- },
67
- "dumps_to_bytes": {
68
- "json.dumps+encode": lambda x: json.dumps(x).encode("utf-8"),
69
- "ujson.dumps_to_bytes": lambda x: ujson.dumps(x).encode("utf-8"),
70
- "orjson.dumps": orjson.dumps,
71
- "ssrjson.dumps_to_bytes": ssrjson.dumps_to_bytes,
72
- },
73
- "dumps_to_bytes(indented2)": {
74
- "json.dumps+encode": lambda x: json.dumps(x, indent=2).encode("utf-8"),
75
- "ujson.dumps_to_bytes": lambda x: ujson.dumps(x, indent=2).encode("utf-8"),
76
- "orjson.dumps": lambda x: orjson.dumps(x, option=orjson.OPT_INDENT_2),
77
- "ssrjson.dumps_to_bytes": lambda x: ssrjson.dumps_to_bytes(x, indent=2),
78
- },
79
- "loads(str)": {
80
- "json.loads": json.loads,
81
- "ujson.loads": ujson.loads,
82
- "orjson.loads": orjson.loads,
83
- "ssrjson.loads": ssrjson.loads,
84
- },
85
- "loads(bytes)": {
86
- "json.loads": json.loads,
87
- "ujson.loads": ujson.loads,
88
- "orjson.loads": orjson.loads,
89
- "ssrjson.loads": ssrjson.loads,
90
- },
91
- }
92
- CATEGORIES = LIBRARIES.keys()
93
-
94
- INDEXES = ["speed"]
95
-
96
-
97
- def gc_prepare():
98
- """
99
- Call collect once, and then disable automatic GC.
100
- Return True if automatic GC was enabled.
101
- """
102
- gc.collect()
103
- gc_was_enabled = gc.isenabled()
104
- if gc_was_enabled:
105
- gc.disable()
106
- return gc_was_enabled
107
-
108
-
109
- def benchmark(repeat_time: int, func, *args):
110
- """
111
- Run repeat benchmark, disabling orjson utf-8 cache.
112
- returns time used (ns).
113
- """
114
- gc_was_enabled = gc_prepare()
115
- try:
116
- # warm up
117
- _ssrjson_benchmark.run_object_accumulate_benchmark(func, 100, args)
118
- return _ssrjson_benchmark.run_object_accumulate_benchmark(
119
- func, repeat_time, args
120
- )
121
- finally:
122
- if gc_was_enabled:
123
- gc.enable()
124
-
125
-
126
- def benchmark_unicode_arg(repeat_time: int, func, unicode: str, *args):
127
- """
128
- Run repeat benchmark, disabling orjson utf-8 cache.
129
- returns time used (ns).
130
- """
131
- gc_was_enabled = gc_prepare()
132
- try:
133
- # warm up
134
- _ssrjson_benchmark.run_unicode_accumulate_benchmark(func, 100, unicode, args)
135
- return _ssrjson_benchmark.run_unicode_accumulate_benchmark(
136
- func, repeat_time, unicode, args
137
- )
138
- finally:
139
- if gc_was_enabled:
140
- gc.enable()
141
-
142
-
143
- def benchmark_invalidate_dump_cache(repeat_time: int, func, raw_bytes: bytes, *args):
144
- """
145
- orjson will use utf-8 cache for the same input,
146
- so we need to invalidate it.
147
- returns time used (ns).
148
- """
149
- # prepare identical data, without sharing objects
150
- data_warmup = [json.loads(raw_bytes) for _ in range(10)]
151
- data = [json.loads(raw_bytes) for _ in range(repeat_time)]
152
- # disable GC
153
- gc_was_enabled = gc_prepare()
154
- try:
155
- # warm up
156
- for i in range(10):
157
- new_args = (data_warmup[i], *args)
158
- _ssrjson_benchmark.run_object_benchmark(func, new_args)
159
- #
160
- total = 0
161
- for i in range(repeat_time):
162
- new_args = (data[i], *args)
163
- total += _ssrjson_benchmark.run_object_benchmark(func, new_args)
164
- return total
165
- finally:
166
- if gc_was_enabled:
167
- gc.enable()
168
-
169
-
170
- def get_benchmark_files() -> list[pathlib.Path]:
171
- return sorted(pathlib.Path(CUR_DIR, "_files").glob("*.json"))
172
-
173
-
174
- def _run_benchmark(
175
- curfile_obj: defaultdict[str, Any],
176
- repeat_times: int,
177
- input_data: str | bytes,
178
- mode: str, # "dumps", etc
179
- ):
180
- print(f"Running benchmark for {mode}")
181
- funcs = LIBRARIES[mode]
182
- cur_obj = curfile_obj[mode]
183
-
184
- def pick_benchmark_func() -> Callable:
185
- if "dumps" in mode and "loads" not in mode:
186
- return benchmark_invalidate_dump_cache
187
- if isinstance(input_data, str) and "loads" in mode:
188
- return benchmark_unicode_arg
189
- return benchmark
190
-
191
- # process = psutil.Process()
192
-
193
- for name, func in funcs.items():
194
- benchmark_func = pick_benchmark_func()
195
-
196
- # t0 = time.perf_counter()
197
- # cpu_times_before = process.cpu_times()
198
- # ctx_before = process.num_ctx_switches()
199
- # mem_before = process.memory_info().rss
200
-
201
- speed = benchmark_func(repeat_times, func, input_data)
202
-
203
- # End measuring
204
- # t1 = time.perf_counter()
205
- # cpu_times_after = process.cpu_times()
206
- # ctx_after = process.num_ctx_switches()
207
-
208
- # user_cpu = cpu_times_after.user - cpu_times_before.user
209
- # system_cpu = cpu_times_after.system - cpu_times_before.system
210
- # voluntary_ctx = ctx_after.voluntary - ctx_before.voluntary
211
- # involuntary_ctx = ctx_after.involuntary - ctx_before.involuntary
212
- # mem_after = process.memory_info().rss
213
-
214
- cur_obj[name] = {
215
- "speed": speed,
216
- # "user_cpu": user_cpu,
217
- # "system_cpu": system_cpu,
218
- # "ctx_vol": voluntary_ctx,
219
- # "ctx_invol": involuntary_ctx,
220
- # "mem_diff": mem_after - mem_before,
221
- # "wall_time": t1 - t0,
222
- }
223
-
224
- funcs_iter = iter(funcs.items())
225
- baseline_name, _ = next(funcs_iter)
226
- baseline_data = cur_obj[baseline_name]
227
- for name, func in funcs_iter:
228
- if name.startswith("ssrjson"):
229
- # debug use, bytes per sec
230
- if "dumps" in mode:
231
- data_obj = json.loads(input_data)
232
- output = func(data_obj)
233
- if "bytes" in mode:
234
- size = len(output)
235
- else:
236
- _, size, _, _ = _ssrjson_benchmark.inspect_pyunicode(output)
237
- else:
238
- size = (
239
- len(input_data)
240
- if isinstance(input_data, bytes)
241
- else _ssrjson_benchmark.inspect_pyunicode(input_data)[1]
242
- )
243
- cur_obj["ssrjson_bytes_per_sec"] = (
244
- size * repeat_times / (cur_obj[name]["speed"] / _NS_IN_ONE_S)
245
- )
246
-
247
- for index in INDEXES:
248
- basename = name.split(".")[0]
249
- if baseline_data[index] == 0:
250
- cur_obj[f"{basename}_{index}_ratio"] = math.inf
251
- else:
252
- cur_obj[f"{basename}_{index}_ratio"] = (
253
- baseline_data[index] / cur_obj[name][index]
254
- )
255
-
256
-
257
- def run_file_benchmark(
258
- file: str, result: defaultdict[str, defaultdict[str, Any]], process_bytes: int
259
- ):
260
- with open(file, "rb") as f:
261
- raw_bytes = f.read()
262
- raw = raw_bytes.decode("utf-8")
263
- base_file_name = os.path.basename(file)
264
- curfile_obj = result[base_file_name]
265
- curfile_obj["byte_size"] = bytes_size = len(raw_bytes)
266
- kind, str_size, is_ascii, _ = _ssrjson_benchmark.inspect_pyunicode(raw)
267
- curfile_obj["pyunicode_size"] = str_size
268
- curfile_obj["pyunicode_kind"] = kind
269
- curfile_obj["pyunicode_is_ascii"] = is_ascii
270
- repeat_times = int((process_bytes + bytes_size - 1) // bytes_size)
271
-
272
- for mode in LIBRARIES.keys():
273
- _run_benchmark(curfile_obj, repeat_times, raw_bytes, mode)
274
-
275
-
276
- def get_head_rev_name():
277
- return (
278
- getattr(ssrjson, "__version__", None) or getattr(ssrjson, "ssrjson").__version__
279
- )
280
-
281
-
282
- def get_real_output_file_name():
283
- rev = get_head_rev_name()
284
- if not rev:
285
- file = "benchmark_result.json"
286
- else:
287
- file = f"benchmark_result_{rev}.json"
288
- return file
289
-
290
-
291
- def get_cpu_name() -> str:
292
- cpuinfo_spec = importlib.util.find_spec("cpuinfo")
293
- if cpuinfo_spec is not None:
294
- import cpuinfo
295
-
296
- cpu_name = cpuinfo.get_cpu_info().get("brand_raw", "UnknownCPU")
297
- else:
298
- # fallback
299
- cpu_name: str = platform.processor()
300
- if cpu_name.strip() == "":
301
- # linux fallback
302
- if os.path.exists("/proc/cpuinfo"):
303
- with open(file="/proc/cpuinfo", mode="r") as file:
304
- cpu_info_lines = file.readlines()
305
- for line in cpu_info_lines:
306
- if "model name" in line:
307
- cpu_name = re.sub(
308
- pattern=r"model name\s+:\s+", repl="", string=line
309
- )
310
- break
311
- else:
312
- cpu_name = "UnknownCPU"
313
- # merge nearby spaces
314
- return re.sub(pattern=r"\s+", repl=" ", string=cpu_name).strip()
315
-
316
-
317
- def get_mem_total() -> str:
318
- mem_total: int = 0
319
- if platform.system() == "Linux":
320
- with open(file="/proc/meminfo", mode="r") as file:
321
- mem_info_lines = file.readlines()
322
- for line in mem_info_lines:
323
- if "MemTotal" in line:
324
- mem_total = int(re.sub(pattern=r"[^0-9]", repl="", string=line))
325
- break
326
- elif platform.system() == "Windows":
327
- import psutil
328
-
329
- mem_total = psutil.virtual_memory().total // (1024 * 1024)
330
- return f"{mem_total / (1024**2):.3f}GiB"
331
-
332
-
333
- def get_ratio_color(ratio: float) -> str:
334
- if ratio < 1:
335
- return "#d63031" # red (worse than baseline)
336
- elif ratio == 1:
337
- return "black" # black (baseline)
338
- elif ratio < 2:
339
- return "#e67e22" # orange (similar/slightly better)
340
- elif ratio < 4:
341
- return "#f39c12" # amber (decent improvement)
342
- elif ratio < 8:
343
- return "#27ae60" # green (good)
344
- elif ratio < 16:
345
- return "#2980b9" # blue (great)
346
- else:
347
- return "#8e44ad" # purple (exceptional)
348
-
349
-
350
- def plot_relative_ops(data: dict, doc_name: str, index_s: str) -> io.BytesIO:
351
- libs = list(LIBRARIES_COLORS.keys())
352
- colors = [LIBRARIES_COLORS[n] for n in libs]
353
- n = len(CATEGORIES)
354
- bar_width = 0.2
355
- inner_pad = 0
356
-
357
- fig, axs = plt.subplots(
358
- 1,
359
- n,
360
- figsize=(4 * n, 6),
361
- sharey=False,
362
- tight_layout=True,
363
- gridspec_kw={"wspace": 0},
364
- )
365
-
366
- x_positions = [i * (bar_width + inner_pad) for i in range(len(libs))]
367
-
368
- for ax, cat in zip(axs, CATEGORIES):
369
- vals = [1.0] + [data[cat][f"{name}_{index_s}_ratio"] for name in libs[1:]]
370
- gbps = (data[cat]["ssrjson_bytes_per_sec"]) / (1024**3)
371
-
372
- for xi, val, col in zip(x_positions, vals, colors):
373
- ax.bar(xi, val, width=bar_width, color=col)
374
- ax.text(
375
- xi,
376
- val + 0.05,
377
- f"{val:.2f}x",
378
- ha="center",
379
- va="bottom",
380
- fontsize=9,
381
- color=get_ratio_color(val),
382
- )
383
-
384
- ssrjson_index = libs.index("ssrjson")
385
- ax.text(
386
- x_positions[ssrjson_index],
387
- vals[ssrjson_index] / 2,
388
- f"{gbps:.2f} GB/s",
389
- ha="center",
390
- va="center",
391
- fontsize=10,
392
- color="#2c3e50",
393
- fontweight="bold",
394
- )
395
-
396
- # baseline line
397
- ax.axhline(1.0, color="gray", linestyle="--", linewidth=1)
398
- # height = 1.1 * max bar height
399
- ax.set_ylim(0, max(vals + [1.0]) * 1.1)
400
-
401
- # hide all tick
402
- ax.tick_params(
403
- axis="both",
404
- which="both",
405
- left=False,
406
- bottom=False,
407
- labelleft=False,
408
- labelbottom=False,
409
- )
410
-
411
- # and spine
412
- for spine in ("left", "top", "right"):
413
- ax.spines[spine].set_visible(False)
414
-
415
- ax.set_xlabel(cat, fontsize=10, labelpad=6)
416
-
417
- fig.suptitle(
418
- doc_name,
419
- fontsize=20,
420
- fontweight="bold",
421
- y=0.98,
422
- )
423
-
424
- # color legend
425
- legend_elements = [
426
- plt.Line2D([0], [0], color=col, lw=4, label=name)
427
- for name, col in LIBRARIES_COLORS.items()
428
- ]
429
- fig.legend(
430
- handles=legend_elements,
431
- loc="upper right",
432
- bbox_to_anchor=(0.98, 0.95),
433
- ncol=len(libs),
434
- fontsize=14,
435
- frameon=False,
436
- )
437
-
438
- fig.text(
439
- 0.5,
440
- 0,
441
- "Higher is better",
442
- ha="center",
443
- va="bottom",
444
- fontsize=8,
445
- style="italic",
446
- color="#555555",
447
- )
448
-
449
- buf = io.BytesIO()
450
- plt.savefig(buf, format="svg", bbox_inches="tight")
451
- buf.seek(0)
452
- plt.close(fig)
453
- return buf
454
-
455
-
456
- def draw_page_number(c: "canvas.Canvas", page_num: int):
457
- from reportlab.lib.pagesizes import A4
458
-
459
- width, _ = A4
460
- c.setFont("Helvetica-Oblique", 8) # italic
461
- c.setFillColorRGB(0.5, 0.5, 0.5) # grey
462
- c.drawRightString(width - 40, 20, f"{page_num}")
463
-
464
-
465
- def generate_pdf_report(
466
- figures: List[List[io.BytesIO]], header_text: str, output_pdf_path: str
467
- ) -> str:
468
- from reportlab.pdfgen import canvas
469
- from reportlab.graphics import renderPDF
470
- from svglib.svglib import svg2rlg
471
- from reportlab.lib.pagesizes import A4
472
-
473
- c = canvas.Canvas(output_pdf_path, pagesize=A4)
474
- width, height = A4
475
-
476
- # heading info
477
- heading = header_text.splitlines()
478
- # first line is # header
479
- header, heading_info = heading[0].removeprefix("#").strip(), heading[1:]
480
- c.setFont(PDF_HEADING_FONT, 20)
481
- text_obj = c.beginText(40, height - 50)
482
- text_obj.textLine(header)
483
- c.drawText(text_obj)
484
-
485
- # Wrap heading_info lines if overflow
486
- max_width = width - 80 # 40 margin on both sides
487
- wrapped_heading_info = []
488
- for line in heading_info:
489
- while c.stringWidth(line, PDF_TEXT_FONT, 10) > max_width:
490
- # Find a split point
491
- split_idx = int(max_width // c.stringWidth(" ", PDF_TEXT_FONT, 10))
492
- # Try to split at nearest space before split_idx
493
- space_idx = line.rfind(" ", 0, split_idx)
494
- if space_idx == -1:
495
- space_idx = split_idx
496
- wrapped_heading_info.append(line[:space_idx])
497
- # TODO fixed indent
498
- line = " " + line[space_idx:].lstrip()
499
- wrapped_heading_info.append(line)
500
- heading_info = wrapped_heading_info
501
-
502
- c.setFont(PDF_TEXT_FONT, 10)
503
- text_obj = c.beginText(40, height - 70)
504
- for line in heading_info:
505
- text_obj.textLine(line)
506
- c.drawText(text_obj)
507
-
508
- c.setFont("Helvetica-Oblique", 8)
509
- text = "This report was generated by https://github.com/Nambers/ssrJSON-benchmark"
510
- c.drawString(40, 20, text)
511
- link_start = 40 + c.stringWidth("This report was generated by ")
512
- link_end = link_start + c.stringWidth(
513
- "https://github.com/Nambers/ssrJSON-benchmark"
514
- )
515
- text_height = 5 # Adjusted height to better fit the link area
516
- c.linkURL(
517
- "https://github.com/Nambers/ssrJSON-benchmark",
518
- (link_start, 20, link_end, 20 + text_height),
519
- relative=1,
520
- )
521
-
522
- header_lines = header_text.count("\n") + 1
523
- header_height = header_lines * 14 + 10
524
- # subheading spacing = 30
525
- y_pos = height - header_height - 30
526
- bottom_margin = 20
527
- vertical_gap = 20
528
-
529
- p = 0
530
-
531
- for name, figs in zip(INDEXES, figures):
532
- text_obj = c.beginText()
533
- text_obj.setTextOrigin(40, y_pos)
534
- text_obj.setFont(PDF_HEADING_FONT, 14)
535
- text_obj.textLine(f"{name}")
536
- c.drawText(text_obj)
537
- c.bookmarkHorizontal(name, 0, y_pos + 20)
538
- c.addOutlineEntry(name, name, level=0)
539
- y_pos -= 20
540
- for svg_io in figs:
541
- svg_io.seek(0)
542
- drawing = svg2rlg(svg_io, font_map=font_map)
543
-
544
- avail_w = width - 80
545
- scale = avail_w / drawing.width
546
- drawing.width *= scale
547
- drawing.height *= scale
548
- drawing.scale(scale, scale)
549
-
550
- img_h = drawing.height
551
- # no enough space
552
- if y_pos - img_h - vertical_gap < bottom_margin:
553
- draw_page_number(c, p)
554
- p += 1
555
- c.showPage()
556
- y_pos = height - bottom_margin
557
-
558
- c.setStrokeColorRGB(0.9, 0.9, 0.9)
559
- c.setLineWidth(0.4)
560
- c.line(40, y_pos, width - 40, y_pos)
561
-
562
- renderPDF.draw(drawing, c, 40, y_pos - img_h)
563
- y_pos -= img_h + vertical_gap
564
-
565
- draw_page_number(c, p)
566
- c.save()
567
- return output_pdf_path
568
-
569
-
570
- def fetch_header(rev) -> str:
571
- with open(os.path.join(CUR_DIR, "template.md"), "r") as f:
572
- template = f.read()
573
- return template.format(
574
- REV=rev,
575
- TIME=time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime()),
576
- OS=f"{platform.system()} {platform.machine()} {platform.release()} {platform.version()}",
577
- PYTHON=sys.version,
578
- ORJSON_VER=orjson.__version__,
579
- UJSON_VER=ujson.__version__,
580
- SIMD_FLAGS=ssrjson.get_current_features(),
581
- CHIPSET=get_cpu_name(),
582
- MEM=get_mem_total(),
583
- )
584
-
585
-
586
- def generate_report(result: dict[str, dict[str, Any]], file: str, out_dir: str = CWD):
587
- file = file.removesuffix(".json")
588
- report_name = f"{file}.pdf"
589
-
590
- figures = []
591
-
592
- for index_s in INDEXES:
593
- tmp = []
594
- for bench_file in get_benchmark_files():
595
- print(f"Processing {bench_file.name}")
596
- tmp.append(
597
- plot_relative_ops(
598
- result[bench_file.name],
599
- bench_file.name,
600
- index_s,
601
- )
602
- )
603
- figures.append(tmp)
604
-
605
- template = fetch_header(
606
- file.removeprefix("benchmark_result_").removesuffix(".json")
607
- )
608
- out_path = generate_pdf_report(
609
- figures,
610
- header_text=template,
611
- output_pdf_path=os.path.join(out_dir, report_name),
612
- )
613
- print(f"Report saved to {out_path}")
614
-
615
-
616
- def generate_report_markdown(
617
- result: dict[str, dict[str, Any]], file: str, out_dir: str = CWD
618
- ):
619
- file = file.removesuffix(".json")
620
- report_name = f"{file}.md"
621
- report_folder = os.path.join(out_dir, f"{file}_report")
622
-
623
- # mkdir
624
- if not os.path.exists(report_folder):
625
- os.makedirs(report_folder)
626
-
627
- template = fetch_header(
628
- file.removeprefix("benchmark_result_").removesuffix(".json")
629
- )
630
-
631
- for index_s in INDEXES:
632
- template += f"\n\n## {index_s}\n\n"
633
- for bench_file in get_benchmark_files():
634
- print(f"Processing {bench_file.name}")
635
- with open(
636
- os.path.join(report_folder, bench_file.name + ".svg"), "wb"
637
- ) as svg_file:
638
- svg_file.write(
639
- plot_relative_ops(
640
- result[bench_file.name],
641
- bench_file.name,
642
- index_s,
643
- ).getvalue()
644
- )
645
- # add svg
646
- template += f"![{bench_file.name}](./{bench_file.name}.svg)\n\n"
647
-
648
- with open(os.path.join(report_folder, report_name), "w") as f:
649
- f.write(template)
650
- print(f"Report saved to {os.path.join(report_folder, report_name)}")
651
-
652
-
653
- def run_benchmark(process_bytes: int = 1e8):
654
- file = get_real_output_file_name()
655
- if os.path.exists(file):
656
- os.remove(file)
657
- result: defaultdict[str, defaultdict[str, Any]] = defaultdict(
658
- lambda: defaultdict(dict)
659
- )
660
-
661
- for bench_file in get_benchmark_files():
662
- run_file_benchmark(bench_file, result, process_bytes)
663
- output_result = json.dumps(result, indent=4)
664
-
665
- with open(f"{file}", "w", encoding="utf-8") as f:
666
- f.write(output_result)
667
- return result, file
668
-
669
-
670
- def run_benchmark_default():
671
- """
672
- Run default benchmark with default parameters. Generate report in PDF.
673
- """
674
- j, file = run_benchmark()
675
- file = file.split("/")[-1]
676
- generate_report(j, file)