|
2 | 2 | import numpy as np |
3 | 3 | import matplotlib.pyplot as plt |
4 | 4 | import os |
5 | | -import csv |
6 | 5 | import argparse |
7 | 6 |
|
8 | 7 | plt.rcParams["figure.figsize"] = [40, 30] |
@@ -52,48 +51,64 @@ def formatBins(df: pd.DataFrame, bins: int): |
52 | 51 | return df |
53 | 52 |
|
54 | 53 |
|
55 | | -def write_csv_output(df_stats, df, csv_path): |
56 | | - """Write statistics to a CSV file""" |
| 54 | +def write_markdown_output(file,df_stats, df, baseline_name, contender_name): |
| 55 | + """Write statistics in markdown table format to a file""" |
57 | 56 | total_blocks = df.block_number.max() - df.block_number.min() |
58 | 57 | time_xt = df.time_x.sum() |
59 | 58 | time_yt = df.time_y.sum() |
60 | 59 | timet = time_yt - time_xt |
61 | 60 |
|
62 | | - with open(csv_path, 'w', newline='') as csvfile: |
63 | | - csv_writer = csv.writer(csvfile) |
| 61 | + file.write(f"\n## {os.path.basename(baseline_name)} vs {os.path.basename(contender_name)}\n\n") |
64 | 62 |
|
65 | | - csv_writer.writerow(['block_range', 'bps_x', 'bps_y', 'tps_x', 'tps_y', |
66 | | - 'time_x', 'time_y', 'bpsd', 'tpsd', 'timed']) |
| 63 | + file.write("| Block Range | BPS Baseline | BPS Contender | TPS Baseline | TPS Contender | Time Baseline | Time Contender | BPS Diff | TPS Diff | Time Diff |\n") |
| 64 | + file.write("|------------|--------------|---------------|--------------|---------------|---------------|----------------|----------|----------|-----------|\n") |
67 | 65 |
|
68 | | - for idx, row in df_stats.iterrows(): |
69 | | - csv_writer.writerow([ |
70 | | - str(idx), # block range |
71 | | - f"{row['bps_x']:.2f}", |
72 | | - f"{row['bps_y']:.2f}", |
73 | | - f"{row['tps_x']:.2f}", |
74 | | - f"{row['tps_y']:.2f}", |
75 | | - prettySecs(row['time_x']), |
76 | | - prettySecs(row['time_y']), |
77 | | - f"{row['bpsd']:.2%}", |
78 | | - f"{row['tpsd']:.2%}", |
79 | | - f"{row['timed']:.2%}" |
80 | | - ]) |
| 66 | + for idx, row in df_stats.iterrows(): |
| 67 | + file.write(f"| {str(idx)} | {row['bps_x']:.2f} | {row['bps_y']:.2f} | {row['tps_x']:.2f} | {row['tps_y']:.2f} | {prettySecs(row['time_x'])} | {prettySecs(row['time_y'])} | {row['bpsd']:.2%} | {row['tpsd']:.2%} | {row['timed']:.2%} |\n") |
81 | 68 |
|
82 | | - csv_writer.writerow([]) |
| 69 | + file.write("\n## Summary\n\n") |
83 | 70 |
|
84 | | - csv_writer.writerow(['Total Blocks', total_blocks]) |
85 | | - csv_writer.writerow(['Baseline Time', prettySecs(time_xt)]) |
86 | | - csv_writer.writerow(['Contender Time', prettySecs(time_yt)]) |
87 | | - csv_writer.writerow(['Time Difference', prettySecs(timet)]) |
88 | | - csv_writer.writerow(['Time Difference %', f"{(timet/time_xt):.2%}"]) |
| 71 | + file.write("| Metric | Value |\n") |
| 72 | + file.write("|--------|-------|\n") |
| 73 | + |
| 74 | + file.write(f"| Total Blocks | {total_blocks} |\n") |
| 75 | + file.write(f"| Baseline Time | {prettySecs(time_xt)} |\n") |
| 76 | + file.write(f"| Contender Time | {prettySecs(time_yt)} |\n") |
| 77 | + file.write(f"| Time Difference | {prettySecs(timet)} |\n") |
| 78 | + file.write(f"| Time Difference % | {(timet/time_xt):.2%} |\n") |
| 79 | + |
| 80 | + file.write("\n## Legend\n\n") |
| 81 | + file.write("- BPS Diff: Blocks per second difference (+)\n") |
| 82 | + file.write("- TPS Diff: Transactions per second difference\n") |
| 83 | + file.write("- Time Diff: Time to process difference (-)\n") |
| 84 | + file.write("\n(+) = more is better, (-) = less is better\n") |
| 85 | + |
| 86 | + |
| 87 | +def write_standard_output(df_stats, df, baseline_name, contender_name): |
| 88 | + print(f"{os.path.basename(baseline_name)} vs {os.path.basename(contender_name)}") |
| 89 | + print(df_stats.to_string( |
| 90 | + formatters=dict.fromkeys(["bpsd", "tpsd", "timed"], "{:,.2%}".format) |
| 91 | + | dict.fromkeys(["bps_x", "bps_y", "tps_x", "tps_y"], "{:,.2f}".format) |
| 92 | + | dict.fromkeys(["time_x", "time_y"], prettySecs), |
| 93 | + )) |
| 94 | + |
| 95 | + total_blocks = df.block_number.max() - df.block_number.min() |
| 96 | + time_xt = df.time_x.sum() |
| 97 | + time_yt = df.time_y.sum() |
| 98 | + timet = time_yt - time_xt |
| 99 | + |
| 100 | + print(f"\nblocks: {total_blocks}, baseline: {prettySecs(time_xt)}, contender: {prettySecs(time_yt)}") |
| 101 | + print(f"Time (total): {prettySecs(timet)}, {(timet/time_xt):.2%}") |
| 102 | + print("\nbpsd = blocks per sec diff (+), tpsd = txs per sec diff, timed = time to process diff (-)") |
| 103 | + print("+ = more is better, - = less is better") |
89 | 104 |
|
90 | 105 |
|
91 | 106 | def main(): |
92 | 107 | parser = argparse.ArgumentParser() |
93 | 108 | parser.add_argument("baseline") |
94 | 109 | parser.add_argument("contender") |
95 | 110 | parser.add_argument("--plot", action="store_true") |
96 | | - parser.add_argument("--csv-output", type=str, help="Path to output CSV file") |
| 111 | + parser.add_argument("--markdown-output", type=str, help="Output path for markdown format file") |
97 | 112 | parser.add_argument( |
98 | 113 | "--bins", |
99 | 114 | default=10, |
@@ -122,8 +137,8 @@ def main(): |
122 | 137 | print(f"Contender range: {min(contender.index)} to {max(contender.index)}") |
123 | 138 | exit(1) |
124 | 139 |
|
125 | | - baseline = baseline.loc[baseline.index >= start and baseline.index <= end] |
126 | | - contender = contender.loc[contender.index >= start and contender.index <= end] |
| 140 | + baseline = baseline.loc[start:end] |
| 141 | + contender = contender.loc[start:end] |
127 | 142 |
|
128 | 143 | # Join the two frames then interpolate - this helps dealing with runs that |
129 | 144 | # haven't been using the same chunking and/or max-blocks |
@@ -173,26 +188,11 @@ def main(): |
173 | 188 | | dict.fromkeys(["bpsd", "tpsd", "timed"], "mean") |
174 | 189 | ) |
175 | 190 |
|
176 | | - if args.csv_output: |
177 | | - write_csv_output(stats_df, df, args.csv_output) |
178 | | - |
179 | | - print(f"{os.path.basename(args.baseline)} vs {os.path.basename(args.contender)}") |
180 | | - print(stats_df.to_string( |
181 | | - formatters=dict.fromkeys(["bpsd", "tpsd", "timed"], "{:,.2%}".format) |
182 | | - | dict.fromkeys(["bps_x", "bps_y", "tps_x", "tps_y"], "{:,.2f}".format) |
183 | | - | dict.fromkeys(["time_x", "time_y"], prettySecs), |
184 | | - )) |
185 | | - |
186 | | - total_blocks = df.block_number.max() - df.block_number.min() |
187 | | - time_xt = df.time_x.sum() |
188 | | - time_yt = df.time_y.sum() |
189 | | - timet = time_yt - time_xt |
190 | | - |
191 | | - print(f"\nblocks: {total_blocks}, baseline: {prettySecs(time_xt)}, contender: {prettySecs(time_yt)}") |
192 | | - print(f"Time (total): {prettySecs(timet)}, {(timet/time_xt):.2%}") |
193 | | - print("\nbpsd = blocks per sec diff (+), tpsd = txs per sec diff, timed = time to process diff (-)") |
194 | | - print("+ = more is better, - = less is better") |
195 | | - |
| 191 | + if args.markdown_output: |
| 192 | + with open(args.markdown_output, 'w') as f: |
| 193 | + write_markdown_output(f, stats_df, df, args.baseline, args.contender) |
| 194 | + else: |
| 195 | + write_standard_output(stats_df, df, args.baseline, args.contender) |
196 | 196 |
|
197 | 197 | if __name__ == "__main__": |
198 | 198 | main() |
0 commit comments