Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## Comprehensive HNSW Benchmark Script
- ## Compares Original vs Optimized implementation
- ## Saves results to CSV and generates plots
- addpath ("inst");
- addpath ("inst/Clustering");
- printf ("\n=== HNSW Benchmark: Original vs Optimized ===\n\n");
- ## Test configurations
- N_values = [100, 250, 500, 1000];
- D_values = [1, 5, 10, 50, 100];
- K = 3;
- num_queries = 10;
- ## Generate all combinations
- num_N = length (N_values);
- num_D = length (D_values);
- total_tests = num_N * num_D;
- ## Storage for results
- results = struct ();
- results.N = zeros (total_tests, 1);
- results.D = zeros (total_tests, 1);
- results.orig_build = zeros (total_tests, 1);
- results.orig_query = zeros (total_tests, 1);
- results.opt_build = zeros (total_tests, 1);
- results.opt_query = zeros (total_tests, 1);
- printf ("Running %d configurations (K=%d, queries=%d)\n", total_tests, K, num_queries);
- printf ("This will take a few minutes...\n\n");
- test_idx = 0;
- for n_idx = 1:num_N
- N = N_values(n_idx);
- for d_idx = 1:num_D
- D = D_values(d_idx);
- test_idx = test_idx + 1;
- printf ("[%2d/%d] N=%4d, D=%3d ... ", test_idx, total_tests, N, D);
- fflush (stdout);
- ## Generate reproducible data
- rand ("seed", 42);
- X = rand (N, D);
- Q = rand (num_queries, D);
- ## Original implementation
- tic; obj1 = hnswSearcher_original (X); b1 = toc;
- tic; [~, ~] = knnsearch (obj1, Q, "K", K); q1 = toc;
- ## Optimized implementation
- tic; obj2 = hnswSearcher (X); b2 = toc;
- tic; [~, ~] = knnsearch (obj2, Q, "K", K); q2 = toc;
- results.N(test_idx) = N;
- results.D(test_idx) = D;
- results.orig_build(test_idx) = b1;
- results.orig_query(test_idx) = q1;
- results.opt_build(test_idx) = b2;
- results.opt_query(test_idx) = q2;
- printf ("Build: %.2fs -> %.2fs | Query: %.3fs -> %.3fs\n", b1, b2, q1, q2);
- fflush (stdout);
- endfor
- endfor
- ## Calculate speedups
- build_speedup = results.orig_build ./ results.opt_build;
- query_speedup = results.orig_query ./ results.opt_query;
- ## Save to CSV
- csv_file = "benchmark_results.csv";
- fid = fopen (csv_file, "w");
- fprintf (fid, "N,D,Original_Build_sec,Original_Query_sec,Optimized_Build_sec,Optimized_Query_sec,Build_Speedup,Query_Speedup\n");
- for i = 1:total_tests
- fprintf (fid, "%d,%d,%.4f,%.4f,%.4f,%.4f,%.2f,%.2f\n", ...
- results.N(i), results.D(i), ...
- results.orig_build(i), results.orig_query(i), ...
- results.opt_build(i), results.opt_query(i), ...
- build_speedup(i), query_speedup(i));
- endfor
- fclose (fid);
- printf ("\n✓ Results saved to %s\n", csv_file);
- ## Print results table
- printf ("\n--- Timing Results (seconds) ---\n");
- printf ("+-------+-----+--------------+--------------+--------------+--------------+\n");
- printf ("| N | D | Orig Build | Orig Query | Opt Build | Opt Query |\n");
- printf ("+-------+-----+--------------+--------------+--------------+--------------+\n");
- for i = 1:total_tests
- printf ("| %5d | %3d | %12.3f | %12.3f | %12.3f | %12.3f |\n", ...
- results.N(i), results.D(i), ...
- results.orig_build(i), results.orig_query(i), ...
- results.opt_build(i), results.opt_query(i));
- endfor
- printf ("+-------+-----+--------------+--------------+--------------+--------------+\n");
- ## Print speedup table
- printf ("\n--- Speedup (Original / Optimized) ---\n");
- printf ("+-------+-----+----------------+----------------+\n");
- printf ("| N | D | Build Speedup | Query Speedup |\n");
- printf ("+-------+-----+----------------+----------------+\n");
- for i = 1:total_tests
- printf ("| %5d | %3d | %12.2fx | %12.2fx |\n", ...
- results.N(i), results.D(i), build_speedup(i), query_speedup(i));
- endfor
- printf ("+-------+-----+----------------+----------------+\n");
- ## Summary statistics
- printf ("\n--- Summary Statistics ---\n");
- printf ("Build Speedup: Min = %.2fx | Max = %.2fx | Mean = %.2fx\n", ...
- min(build_speedup), max(build_speedup), mean(build_speedup));
- printf ("Query Speedup: Min = %.2fx | Max = %.2fx | Mean = %.2fx\n", ...
- min(query_speedup), max(query_speedup), mean(query_speedup));
- ## Generate plots
- printf ("\nGenerating plots...\n");
- colors = {"r", "g", "b", "m", "c"};
- markers = {"o", "s", "d", "^", "v"};
- ## Plot 1: Speedup comparison
- figure (1, "visible", "off");
- clf;
- set (gcf, "paperposition", [0 0 12 5]);
- subplot (1, 2, 1);
- hold on;
- for d_idx = 1:num_D
- D = D_values(d_idx);
- mask = results.D == D;
- plot (results.N(mask), build_speedup(mask), [colors{d_idx} "-" markers{d_idx}], ...
- "linewidth", 2, "markersize", 8, "markerfacecolor", colors{d_idx});
- endfor
- xlabel ("Dataset Size (N)", "fontsize", 11);
- ylabel ("Speedup (x)", "fontsize", 11);
- title ("Build Time Speedup", "fontsize", 12, "fontweight", "bold");
- legend (arrayfun (@(d) sprintf("D=%d", d), D_values, "UniformOutput", false), ...
- "location", "northwest", "fontsize", 9);
- grid on;
- set (gca, "fontsize", 10);
- ylim ([0.9 max(build_speedup)*1.15]);
- subplot (1, 2, 2);
- hold on;
- for d_idx = 1:num_D
- D = D_values(d_idx);
- mask = results.D == D;
- plot (results.N(mask), query_speedup(mask), [colors{d_idx} "-" markers{d_idx}], ...
- "linewidth", 2, "markersize", 8, "markerfacecolor", colors{d_idx});
- endfor
- xlabel ("Dataset Size (N)", "fontsize", 11);
- ylabel ("Speedup (x)", "fontsize", 11);
- title ("Query Time Speedup", "fontsize", 12, "fontweight", "bold");
- legend (arrayfun (@(d) sprintf("D=%d", d), D_values, "UniformOutput", false), ...
- "location", "northwest", "fontsize", 9);
- grid on;
- set (gca, "fontsize", 10);
- ylim ([0.9 max(query_speedup)*1.15]);
- print (1, "benchmark_speedup.png", "-dpng", "-r200");
- printf ("✓ Speedup plot saved to benchmark_speedup.png\n");
- ## Plot 2: Timing comparison
- figure (2, "visible", "off");
- clf;
- set (gcf, "paperposition", [0 0 12 5]);
- subplot (1, 2, 1);
- bar_data = [];
- for n_idx = 1:num_N
- N = N_values(n_idx);
- mask = results.N == N;
- bar_data = [bar_data; mean(results.orig_build(mask)), mean(results.opt_build(mask))];
- endfor
- h = bar (bar_data, 0.8);
- set (h(1), "facecolor", [0.2 0.4 0.8]);
- set (h(2), "facecolor", [0.9 0.4 0.2]);
- set (gca, "xticklabel", N_values, "fontsize", 10);
- xlabel ("Dataset Size (N)", "fontsize", 11);
- ylabel ("Build Time (seconds)", "fontsize", 11);
- title ("Mean Build Time by N", "fontsize", 12, "fontweight", "bold");
- legend ({"Original", "Optimized"}, "location", "northwest", "fontsize", 9);
- grid on;
- subplot (1, 2, 2);
- bar_data = [];
- for n_idx = 1:num_N
- N = N_values(n_idx);
- mask = results.N == N;
- bar_data = [bar_data; mean(results.orig_query(mask)), mean(results.opt_query(mask))];
- endfor
- h = bar (bar_data, 0.8);
- set (h(1), "facecolor", [0.2 0.4 0.8]);
- set (h(2), "facecolor", [0.9 0.4 0.2]);
- set (gca, "xticklabel", N_values, "fontsize", 10);
- xlabel ("Dataset Size (N)", "fontsize", 11);
- ylabel ("Query Time (seconds)", "fontsize", 11);
- title ("Mean Query Time by N", "fontsize", 12, "fontweight", "bold");
- legend ({"Original", "Optimized"}, "location", "northwest", "fontsize", 9);
- grid on;
- print (2, "benchmark_timing.png", "-dpng", "-r200");
- printf ("✓ Timing plot saved to benchmark_timing.png\n");
- printf ("\nBenchmark complete!\n\n");
Advertisement
Add Comment
Please, Sign In to add comment