diff --git a/tests/requirements.txt b/tests/requirements.txt index 4f04d14..0ebe18e 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,2 +1,4 @@ iperf3 -requests \ No newline at end of file +requests +matplotlib +numpy diff --git a/tests/results/Benchmark-chart-with-load.png b/tests/results/Benchmark-chart-with-load.png index 54d48fb..fffb8b8 100644 Binary files a/tests/results/Benchmark-chart-with-load.png and b/tests/results/Benchmark-chart-with-load.png differ diff --git a/tests/results/Benchmark-chart.png b/tests/results/Benchmark-chart.png index 39d9400..d621728 100644 Binary files a/tests/results/Benchmark-chart.png and b/tests/results/Benchmark-chart.png differ diff --git a/tests/results/istogramma_nfproxy.png b/tests/results/istogramma_nfproxy.png index f8b6dfb..a21f264 100644 Binary files a/tests/results/istogramma_nfproxy.png and b/tests/results/istogramma_nfproxy.png differ diff --git a/tests/results/istrogramma_compare.png b/tests/results/istrogramma_compare.png index 0cf60bd..effb105 100644 Binary files a/tests/results/istrogramma_compare.png and b/tests/results/istrogramma_compare.png differ diff --git a/tests/results/test-firegex.csv b/tests/results/test-firegex.csv deleted file mode 100644 index 905d71e..0000000 --- a/tests/results/test-firegex.csv +++ /dev/null @@ -1,52 +0,0 @@ -;2.3.3-1T;2.3.3-8T;2.4.0-1T;2.4.0-8T;2.5.1-1T;2.5.1-8T;;With Load;2.5.1-1T;2.5.1-8T -0;4090,616;3789,988;4216,05;4203,31;3245,763;4007,679;;0;710,619;1790,382 -1;2211,62;2069,487;4239,598;4283,392;3283,646;3963,986;;1;887,877;1933,881 -2;1165,45;1484,554;2418,527;2383,415;3741,157;4222,243;;2;981,431;1941,564 -3;849,39;956,972;2227,8;2419,701;3691,206;3640,707;;3;1081,412;1926,518 -4;828,635;1052,873;2045,351;2038,823;3365,134;4388,553;;4;1038,514;1945,295 -5;741,537;739,658;2066,161;2038;3691,457;3636,047;;5;1029,805;1734,462 -6;632,721;534,722;2214,416;2160,869;3354,807;3644,611;;6;928,317;2009,994 -7;624,772;638,524;2052,845;2192,641;3526,728;3547,39;;7;1130,938;2007,538 -8;529,234;573,833;2195,199;2216,766;3252,62;3412,162;;8;1165,42;2004,825 -9;469,688;531,658;2186,867;2762,56;3551,086;3632,367;;9;925,632;1848,551 -10;336,33;476,167;2147,534;2160,398;3561,506;3536,655;;10;949,483;1836,558 -11;427,783;443,746;2186,652;2147,886;3525,577;3820,019;;11;1021,973;1977,19 -12;400,662;406,027;2178,036;2146,47;2776,064;3677,177;;12;903,878;1987,207 -13;335,086;385,739;2182,151;2158,101;3541,86;3366,323;;13;1001,53;2007,422 -14;342,042;341,563;2185,324;2154,025;3501,34;3353,031;;14;895,351;1994,914 -15;307,283;318,699;1812,911;1997,694;3692,092;3392,423;;15;1026,722;1982,997 -16;239,694;303,722;2144,689;2028,288;3637,166;3330,368;;16;634,727;1955,828 -17;295,163;284,924;2163,525;2005,373;3617,031;3363,272;;17;744,758;1705,883 -18;285,787;284,336;2073,89;2153,945;3700,092;4027,34;;18;978,59;1983,501 -19;254,402;267,32;2071,682;2190,799;3176,831;3467,982;;19;962,375;1951,311 -20;250,553;202,74;2153,502;2169,302;3368,038;3607,754;;20;997,471;1921,772 -21;227,146;243,849;2144,04;2139,842;3716,577;3767,614;;21;929,785;1956,908 -22;238,747;226,082;2118,517;2155,307;3452,917;3340,544;;22;1200,83;1948,865 -23;234,718;214,348;2141,19;2152,223;3617,604;4086,612;;23;1257,741;1929,387 -24;210,484;216,8;2167,103;2124,155;3651,796;3784,164;;24;772,729;1814,539 -25;210,697;188,98;2168,631;2103,135;3552,053;3496,518;;25;683,913;2084,284 -26;205,943;158,68;2165,555;2148,053;3843,18;3543,808;;26;1188,17;1830,901 -27;202,568;166,556;2158,424;2163,366;3720,406;3453,934;;27;919,961;1946,713 -28;194,341;148,287;2188,376;2122,339;3431,1;3546,188;;28;922,225;1958,238 -29;189,916;149,681;2165,311;2064,701;3578,973;3458,804;;29;1066,286;1906,573 -30;154,228;177,043;2168,158;2134,748;3561,994;3728,609;;30;979,399;1895,341 -31;168,922;175,321;2108,045;1632,533;3524,566;3697,624;;31;978,917;1986,09 -32;173,623;165,312;2121,414;2082,309;3567,537;3698,191;;32;988,415;1943,785 -33;125,431;166,943;2022,533;1878,795;3626,767;3673,973;;33;1061,523;1879,917 -34;162,154;159,026;1888,759;2009,28;3498,361;3690,046;;34;942,85;1946,029 -35;149,865;156,759;2022,837;1987,424;3621,396;3663,799;;35;1045,949;1858,958 -36;150,088;150,216;2015,042;1748,364;3297,839;3540,004;;36;883,941;2009,44 -37;146,085;144,932;1920,401;1725,66;3541,207;3857,604;;37;958,41;1876,749 -38;137,182;146,088;2005,037;1967,877;3560,364;3426,215;;38;989,523;1967,254 -39;138,686;135,897;2028,856;1854,637;3589,746;3704,176;;39;1001,121;1968,595 -40;136,302;136,99;2010,43;1903,963;3686,673;3796,133;;40;1080,079;1846,438 -41;132,707;128,557;1522,342;1987,138;3463,811;3604,623;;41;1151,938;1955,897 -42;100,928;100,307;1525,635;1532,547;3428,408;3650,508;;42;1221,644;1986,446 -43;126,414;103,249;1912,05;1569,27;3753,139;3501,861;;43;991,855;1965,143 -44;125,271;123,49;1920,256;1535,941;3368,89;3685,992;;44;1088,344;1963,016 -45;117,839;120,39;1753,645;1941,715;3324,876;3623,404;;45;973,641;1890,88 -46;89,494;118,055;1476,977;2014,504;3614,895;3728,601;;46;952,35;1998,801 -47;116,939;115;1888,645;2005,794;3245,942;3844,994;;47;1089,644;1682,048 -48;112,517;112,593;1949,103;2022,972;3257,925;3820,046;;48;939,615;2023,688 -49;111,369;109,55;1684,633;1740,836;3200,585;3680,976;;49;1258,419;1982,952 -50;108,568;109,512;1493,935;1726,444;3321,55;3797,432;;50;949,414;1993,641 \ No newline at end of file diff --git a/tests/results/whisker_compare.png b/tests/results/whisker_compare.png index fe9e7fb..8f00fac 100644 Binary files a/tests/results/whisker_compare.png and b/tests/results/whisker_compare.png differ diff --git a/tests/results/whisker_nfproxy.png b/tests/results/whisker_nfproxy.png index bf6b235..a85b3a3 100644 Binary files a/tests/results/whisker_nfproxy.png and b/tests/results/whisker_nfproxy.png differ diff --git a/tests/results_plotter.py b/tests/results_plotter.py new file mode 100644 index 0000000..f4adf92 --- /dev/null +++ b/tests/results_plotter.py @@ -0,0 +1,308 @@ + +import matplotlib.pyplot as plt +import numpy as np +import csv +from matplotlib.ticker import MaxNLocator +from matplotlib import cm + +plt.style.use('fivethirtyeight') +colors = cm.Set1.colors # Use a different strong color palette + +files = [ + ("2.5.1 1T", "results/2.5.1-1T.csv"), + ("2.5.1 8T", "results/2.5.1-8T.csv"), + ("2.3.3 1T", "results/2.3.3-1T.csv"), + ("2.3.3 8T", "results/2.3.3-8T.csv"), + ("2.4.0 1T", "results/2.4.0-1T.csv"), + ("2.4.0 8T", "results/2.4.0-8T.csv"), +] + +output = "results/Benchmark-chart.png" + +data_dict = {} + +for label, file in files: + with open(file, 'r') as csvfile: + reader = csv.reader(csvfile) + data = [list(map(float, row)) for row in reader] + data_dict[label] = data + +fig, ax = plt.subplots() + +for label in data_dict.keys(): + data = data_dict[label] + ax.plot( + list(map(lambda d: int(d[0]),data)), + list(map(lambda d: d[1],data)), + label=label + ) + +ax.set_xlabel("N. of regex", fontname="Roboto", fontsize=12) +ax.set_ylabel("MB/s", fontname="Roboto", fontsize=12) +ax.legend(prop={'family': 'Roboto', 'size': 10}) +ax.legend( + title_fontsize=12, + loc="upper center", + bbox_to_anchor=(0.5, -0.1), + frameon=True, + shadow=True, + borderpad=1, + fontsize=10, + fancybox=True, + ncol=len(data_dict.keys()) # Make the legend horizontal +) +ax.set_xticks(np.arange(0, max(map(lambda d: int(d[0]), data)), step=3)) +ax.set_yticks(np.arange(0, max(map(lambda d: d[1], data)), step=300)) +plt.subplots_adjust(bottom=0.2) # Adjust the bottom margin to make space for the legend +ax.set_title("Firegex benchmark (nfregex)", fontweight='bold', fontname="Roboto", pad=20) +fig.set_size_inches(12, 8) # Set the figure size to make the image larger + +#plt.show() +plt.savefig(output, dpi=300, bbox_inches='tight') +plt.close() + +files = [ + ("2.5.1 1T", "results/2.5.1-1T-withload.csv"), + ("2.5.1 8T", "results/2.5.1-8T-withload.csv"), +] + +output = "results/Benchmark-chart-with-load.png" + +data_dict = {} + +for label, file in files: + with open(file, 'r') as csvfile: + reader = csv.reader(csvfile) + data = [list(map(float, row)) for row in reader] + data_dict[label] = data + +fig, ax = plt.subplots() + +for label in data_dict.keys(): + data = data_dict[label] + ax.plot( + list(map(lambda d: int(d[0]), data)), + list(map(lambda d: d[1], data)), + label=label + ) + +ax.set_xlabel("N. of regex", fontname="Roboto", fontsize=12) +ax.set_ylabel("MB/s", fontname="Roboto", fontsize=12) +ax.legend(prop={'family': 'Roboto', 'size': 10}) +ax.legend( + title_fontsize=12, + loc="upper center", + bbox_to_anchor=(0.5, -0.1), + frameon=True, + shadow=True, + borderpad=1, + fontsize=10, + fancybox=True, + ncol=len(data_dict.keys()) +) +ax.set_xticks(np.arange(0, max(map(lambda d: int(d[0]), data)), step=3)) +ax.set_yticks(np.arange(0, max(map(lambda d: d[1], data)), step=150)) +plt.subplots_adjust(bottom=0.2) +ax.set_title("Load test firegex (nfregex)", fontweight='bold', fontname="Roboto", pad=20) +fig.set_size_inches(12, 8) + +# Calculate the minimum and maximum y values across all data +all_y_values = [d[1] for data in data_dict.values() for d in data] +y_min, y_max = min(all_y_values), max(all_y_values) + +# Set the y-axis limits to skip unused parts +ax.set_ylim(y_min - (y_max - y_min) * 0.1, y_max + (y_max - y_min) * 0.1) + +# Ensure y-ticks are integers if applicable +ax.yaxis.set_major_locator(MaxNLocator(integer=True)) + +#plt.show() +plt.savefig(output, dpi=300, bbox_inches='tight') +plt.close() + +files_nfproxy = [ + ("NfProxy 1T", "results/comparemark_nfproxy_1T.csv"), + ("NfProxy 8T", "results/comparemark_nfproxy_8T.csv"), +] + +output_whisker = "results/whisker_nfproxy.png" +output_histogram = "results/istogramma_nfproxy.png" + +# Read and process data for nfproxy +data_nfproxy = {} +for label, file in files_nfproxy: + with open(file, 'r') as csvfile: + reader = csv.reader(csvfile) + next(reader) # Skip the header + data = [(float(row[0]), float(row[1])) for row in reader] + data_nfproxy[label+" no filter"] = [ele[0] for ele in data] + data_nfproxy[label+" test"] = [ele[1] for ele in data] + +# Generate whisker plot for nfproxy +fig, ax = plt.subplots() + +y_max = max([max(data) for data in data_nfproxy.values()]) +y_min = min([min(data) for data in data_nfproxy.values()]) + +for i, (label, data) in enumerate(data_nfproxy.items()): + ax.boxplot( + data, + positions=[list(data_nfproxy.keys()).index(label)], + tick_labels=[label], + boxprops=dict(color="black", facecolor=colors[i % len(colors)], linewidth=1.3), + whiskerprops=dict(color="black", linewidth=1.3), + capprops=dict(color="black", linewidth=1.3), + medianprops=dict(color="black", linewidth=1.3), + patch_artist=True, # Enable filling the box with color + widths=0.35 # Increase the width of the boxes + ) + +ax.set_yticks(np.arange(0, int(y_max) + 100, step=100)) # Ensure the range includes y_max + +# Set the y-axis limits to skip unused parts +ax.set_ylim(y_min - (y_max - y_min) * 0.1, y_max + (y_max - y_min) * 0.1) + +ax.set_title("NFProxy Benchmarks", fontweight='bold', fontname="Roboto", pad=20) +ax.set_ylabel("MB/s", fontname="Roboto", fontsize=12) +fig.set_size_inches(12, 8) + +#plt.show() +plt.savefig(output_whisker, dpi=300) +plt.close() + +# Generate bar chart with average data for nfproxy +average_data = {label: np.mean(data) for label, data in data_nfproxy.items()} + +fig, ax = plt.subplots() +y_max = max(average_data.values()) + +bars = ax.bar( + average_data.keys(), + average_data.values(), + color=[colors[i % len(colors)] for i in range(len(average_data))], + edgecolor="black", + width=0.4 # Make the bars narrower +) + +ax.set_yticks(np.arange(0, int(y_max) + 100, step=100)) # Ensure the range includes y_max +ax.set_title("NFProxy Benchmarks", fontweight='bold', fontname="Roboto", pad=20) +ax.set_ylabel("Average MB/s", fontname="Roboto", fontsize=12) +ax.set_xticklabels(average_data.keys(), fontname="Roboto", fontsize=12) + +# Annotate bars with their values +for bar in bars: + height = bar.get_height() + ax.annotate( + f'{height:.2f}', + xy=(bar.get_x() + bar.get_width() / 2, height), + xytext=(0, 3), # Offset text above the bar + textcoords="offset points", + ha='center', + va='bottom', + fontsize=10, + fontname="Roboto" + ) + +fig.set_size_inches(12, 8) +plt.tight_layout() + +#plt.show() +plt.savefig(output_histogram, dpi=300, bbox_inches='tight') +plt.close() + +files_nfregex = [ + ("NfRegex 1T", "results/comparemark_nfregex_1T.csv"), + ("NfRegex 8T", "results/comparemark_nfregex_8T.csv"), +] + +output_whisker = "results/whisker_compare.png" +output_histogram = "results/istrogramma_compare.png" + +# Read and process data for nfregex +data_nfregex = {} +for label, file in files_nfregex: + with open(file, 'r') as csvfile: + reader = csv.reader(csvfile) + next(reader) # Skip the header + data = [(float(row[0]), float(row[1])) for row in reader] + data_nfregex[label + " no filter"] = [ele[0] for ele in data] + data_nfregex[label + " test"] = [ele[1] for ele in data] + +# Combine nfproxy and nfregex data +combined_data = {**data_nfproxy, **data_nfregex} + +# Generate whisker plot for combined data +fig, ax = plt.subplots() + +y_max = max([max(data) for data in combined_data.values()]) +y_min = min([min(data) for data in combined_data.values()]) + +for i, (label, data) in enumerate(combined_data.items()): + ax.boxplot( + data, + positions=[list(combined_data.keys()).index(label)], + boxprops=dict(color="black", facecolor=colors[i % len(colors)], linewidth=1.3), + whiskerprops=dict(color="black", linewidth=1.3), + capprops=dict(color="black", linewidth=1.3), + medianprops=dict(color="black", linewidth=1.3), + patch_artist=True, # Enable filling the box with color + widths=0.6 # Increase the width of the boxes + ) + +ax.set_xticks(range(len(combined_data.keys()))) +ax.set_xticklabels(combined_data.keys(), fontname="Roboto", fontsize=10) +ax.set_yticks(np.arange(0, int(y_max) + 100, step=250)) # Ensure the range includes y_max +plt.subplots_adjust(bottom=0.12) + +# Set the y-axis limits to skip unused parts +ax.set_ylim(y_min - (y_max - y_min) * 0.1, y_max + (y_max - y_min) * 0.1) + +ax.set_title("Combined Benchmarks (NFProxy vs NFRegex)", fontweight='bold', fontname="Roboto", pad=20) +ax.set_ylabel("MB/s", fontname="Roboto", fontsize=12) +fig.set_size_inches(14, 8) + +#plt.show() +plt.savefig(output_whisker, dpi=300, bbox_inches='tight') +plt.close() + +# Generate bar chart with average data for combined data +average_combined_data = {label: np.mean(data) for label, data in combined_data.items()} + +fig, ax = plt.subplots() +y_max = max(average_combined_data.values()) + +bars = ax.bar( + average_combined_data.keys(), + average_combined_data.values(), + color=[colors[0 if "nfregex" in ele.lower() else 1] for ele in average_combined_data], + edgecolor="black", + width=0.4 # Make the bars narrower +) + +ax.set_xticks(range(len(average_combined_data.keys()))) +ax.set_xticklabels(average_combined_data.keys(), fontname="Roboto", fontsize=10) +ax.set_yticks(np.arange(0, int(y_max) + 100, step=200)) # Ensure the range includes y_max +ax.set_title("Combined Benchmarks (NFProxy vs NFRegex)", fontweight='bold', fontname="Roboto", pad=20) +ax.set_ylabel("Average MB/s", fontname="Roboto", fontsize=12) + +# Annotate bars with their values +for bar in bars: + height = bar.get_height() + ax.annotate( + f'{height:.2f}', + xy=(bar.get_x() + bar.get_width() / 2, height), + xytext=(0, 3), # Offset text above the bar + textcoords="offset points", + ha='center', + va='bottom', + fontsize=10, + fontname="Roboto" + ) + +fig.set_size_inches(14, 8) +plt.tight_layout() + +#plt.show() +plt.savefig(output_histogram, dpi=300, bbox_inches='tight') +plt.close() +