Beingamanforever

HNSW Benchmarking script

Jan 21st, 2026
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Octave 7.23 KB | None | 0 0
  1. ## Comprehensive HNSW Benchmark Script
  2. ## Compares Original vs Optimized implementation
  3. ## Saves results to CSV and generates plots
  4.  
  5. addpath ("inst");
  6. addpath ("inst/Clustering");
  7.  
  8. printf ("\n=== HNSW Benchmark: Original vs Optimized ===\n\n");
  9.  
  10. ## Test configurations
  11. N_values = [100, 250, 500, 1000];
  12. D_values = [1, 5, 10, 50, 100];
  13. K = 3;
  14. num_queries = 10;
  15.  
  16. ## Generate all combinations
  17. num_N = length (N_values);
  18. num_D = length (D_values);
  19. total_tests = num_N * num_D;
  20.  
  21. ## Storage for results
  22. results = struct ();
  23. results.N = zeros (total_tests, 1);
  24. results.D = zeros (total_tests, 1);
  25. results.orig_build = zeros (total_tests, 1);
  26. results.orig_query = zeros (total_tests, 1);
  27. results.opt_build = zeros (total_tests, 1);
  28. results.opt_query = zeros (total_tests, 1);
  29.  
  30. printf ("Running %d configurations (K=%d, queries=%d)\n", total_tests, K, num_queries);
  31. printf ("This will take a few minutes...\n\n");
  32.  
  33. test_idx = 0;
  34. for n_idx = 1:num_N
  35.   N = N_values(n_idx);
  36.   for d_idx = 1:num_D
  37.     D = D_values(d_idx);
  38.     test_idx = test_idx + 1;
  39.    
  40.     printf ("[%2d/%d] N=%4d, D=%3d ... ", test_idx, total_tests, N, D);
  41.     fflush (stdout);
  42.    
  43.     ## Generate reproducible data
  44.     rand ("seed", 42);
  45.     X = rand (N, D);
  46.     Q = rand (num_queries, D);
  47.    
  48.     ## Original implementation
  49.     tic; obj1 = hnswSearcher_original (X); b1 = toc;
  50.     tic; [~, ~] = knnsearch (obj1, Q, "K", K); q1 = toc;
  51.    
  52.     ## Optimized implementation  
  53.     tic; obj2 = hnswSearcher (X); b2 = toc;
  54.     tic; [~, ~] = knnsearch (obj2, Q, "K", K); q2 = toc;
  55.    
  56.     results.N(test_idx) = N;
  57.     results.D(test_idx) = D;
  58.     results.orig_build(test_idx) = b1;
  59.     results.orig_query(test_idx) = q1;
  60.     results.opt_build(test_idx) = b2;
  61.     results.opt_query(test_idx) = q2;
  62.    
  63.     printf ("Build: %.2fs -> %.2fs  |  Query: %.3fs -> %.3fs\n", b1, b2, q1, q2);
  64.     fflush (stdout);
  65.   endfor
  66. endfor
  67.  
  68. ## Calculate speedups
  69. build_speedup = results.orig_build ./ results.opt_build;
  70. query_speedup = results.orig_query ./ results.opt_query;
  71.  
  72. ## Save to CSV
  73. csv_file = "benchmark_results.csv";
  74. fid = fopen (csv_file, "w");
  75. fprintf (fid, "N,D,Original_Build_sec,Original_Query_sec,Optimized_Build_sec,Optimized_Query_sec,Build_Speedup,Query_Speedup\n");
  76. for i = 1:total_tests
  77.   fprintf (fid, "%d,%d,%.4f,%.4f,%.4f,%.4f,%.2f,%.2f\n", ...
  78.            results.N(i), results.D(i), ...
  79.            results.orig_build(i), results.orig_query(i), ...
  80.            results.opt_build(i), results.opt_query(i), ...
  81.            build_speedup(i), query_speedup(i));
  82. endfor
  83. fclose (fid);
  84. printf ("\n✓ Results saved to %s\n", csv_file);
  85.  
  86. ## Print results table
  87. printf ("\n--- Timing Results (seconds) ---\n");
  88. printf ("+-------+-----+--------------+--------------+--------------+--------------+\n");
  89. printf ("|   N   |  D  | Orig Build   | Orig Query   |  Opt Build   |  Opt Query   |\n");
  90. printf ("+-------+-----+--------------+--------------+--------------+--------------+\n");
  91. for i = 1:total_tests
  92.   printf ("| %5d | %3d | %12.3f | %12.3f | %12.3f | %12.3f |\n", ...
  93.           results.N(i), results.D(i), ...
  94.           results.orig_build(i), results.orig_query(i), ...
  95.           results.opt_build(i), results.opt_query(i));
  96. endfor
  97. printf ("+-------+-----+--------------+--------------+--------------+--------------+\n");
  98.  
  99. ## Print speedup table
  100. printf ("\n--- Speedup (Original / Optimized) ---\n");
  101. printf ("+-------+-----+----------------+----------------+\n");
  102. printf ("|   N   |  D  | Build Speedup  | Query Speedup  |\n");
  103. printf ("+-------+-----+----------------+----------------+\n");
  104. for i = 1:total_tests
  105.   printf ("| %5d | %3d | %12.2fx   | %12.2fx   |\n", ...
  106.           results.N(i), results.D(i), build_speedup(i), query_speedup(i));
  107. endfor
  108. printf ("+-------+-----+----------------+----------------+\n");
  109.  
  110. ## Summary statistics
  111. printf ("\n--- Summary Statistics ---\n");
  112. printf ("Build Speedup:  Min = %.2fx  |  Max = %.2fx  |  Mean = %.2fx\n", ...
  113.         min(build_speedup), max(build_speedup), mean(build_speedup));
  114. printf ("Query Speedup:  Min = %.2fx  |  Max = %.2fx  |  Mean = %.2fx\n", ...
  115.         min(query_speedup), max(query_speedup), mean(query_speedup));
  116.  
  117. ## Generate plots
  118. printf ("\nGenerating plots...\n");
  119.  
  120. colors = {"r", "g", "b", "m", "c"};
  121. markers = {"o", "s", "d", "^", "v"};
  122.  
  123. ## Plot 1: Speedup comparison
  124. figure (1, "visible", "off");
  125. clf;
  126. set (gcf, "paperposition", [0 0 12 5]);
  127.  
  128. subplot (1, 2, 1);
  129. hold on;
  130. for d_idx = 1:num_D
  131.   D = D_values(d_idx);
  132.   mask = results.D == D;
  133.   plot (results.N(mask), build_speedup(mask), [colors{d_idx} "-" markers{d_idx}], ...
  134.         "linewidth", 2, "markersize", 8, "markerfacecolor", colors{d_idx});
  135. endfor
  136. xlabel ("Dataset Size (N)", "fontsize", 11);
  137. ylabel ("Speedup (x)", "fontsize", 11);
  138. title ("Build Time Speedup", "fontsize", 12, "fontweight", "bold");
  139. legend (arrayfun (@(d) sprintf("D=%d", d), D_values, "UniformOutput", false), ...
  140.         "location", "northwest", "fontsize", 9);
  141. grid on;
  142. set (gca, "fontsize", 10);
  143. ylim ([0.9 max(build_speedup)*1.15]);
  144.  
  145. subplot (1, 2, 2);
  146. hold on;
  147. for d_idx = 1:num_D
  148.   D = D_values(d_idx);
  149.   mask = results.D == D;
  150.   plot (results.N(mask), query_speedup(mask), [colors{d_idx} "-" markers{d_idx}], ...
  151.         "linewidth", 2, "markersize", 8, "markerfacecolor", colors{d_idx});
  152. endfor
  153. xlabel ("Dataset Size (N)", "fontsize", 11);
  154. ylabel ("Speedup (x)", "fontsize", 11);
  155. title ("Query Time Speedup", "fontsize", 12, "fontweight", "bold");
  156. legend (arrayfun (@(d) sprintf("D=%d", d), D_values, "UniformOutput", false), ...
  157.         "location", "northwest", "fontsize", 9);
  158. grid on;
  159. set (gca, "fontsize", 10);
  160. ylim ([0.9 max(query_speedup)*1.15]);
  161.  
  162. print (1, "benchmark_speedup.png", "-dpng", "-r200");
  163. printf ("✓ Speedup plot saved to benchmark_speedup.png\n");
  164.  
  165. ## Plot 2: Timing comparison
  166. figure (2, "visible", "off");
  167. clf;
  168. set (gcf, "paperposition", [0 0 12 5]);
  169.  
  170. subplot (1, 2, 1);
  171. bar_data = [];
  172. for n_idx = 1:num_N
  173.   N = N_values(n_idx);
  174.   mask = results.N == N;
  175.   bar_data = [bar_data; mean(results.orig_build(mask)), mean(results.opt_build(mask))];
  176. endfor
  177. h = bar (bar_data, 0.8);
  178. set (h(1), "facecolor", [0.2 0.4 0.8]);
  179. set (h(2), "facecolor", [0.9 0.4 0.2]);
  180. set (gca, "xticklabel", N_values, "fontsize", 10);
  181. xlabel ("Dataset Size (N)", "fontsize", 11);
  182. ylabel ("Build Time (seconds)", "fontsize", 11);
  183. title ("Mean Build Time by N", "fontsize", 12, "fontweight", "bold");
  184. legend ({"Original", "Optimized"}, "location", "northwest", "fontsize", 9);
  185. grid on;
  186.  
  187. subplot (1, 2, 2);
  188. bar_data = [];
  189. for n_idx = 1:num_N
  190.   N = N_values(n_idx);
  191.   mask = results.N == N;
  192.   bar_data = [bar_data; mean(results.orig_query(mask)), mean(results.opt_query(mask))];
  193. endfor
  194. h = bar (bar_data, 0.8);
  195. set (h(1), "facecolor", [0.2 0.4 0.8]);
  196. set (h(2), "facecolor", [0.9 0.4 0.2]);
  197. set (gca, "xticklabel", N_values, "fontsize", 10);
  198. xlabel ("Dataset Size (N)", "fontsize", 11);
  199. ylabel ("Query Time (seconds)", "fontsize", 11);
  200. title ("Mean Query Time by N", "fontsize", 12, "fontweight", "bold");
  201. legend ({"Original", "Optimized"}, "location", "northwest", "fontsize", 9);
  202. grid on;
  203.  
  204. print (2, "benchmark_timing.png", "-dpng", "-r200");
  205. printf ("✓ Timing plot saved to benchmark_timing.png\n");
  206.  
  207. printf ("\nBenchmark complete!\n\n");
Advertisement
Add Comment
Please, Sign In to add comment