@@ -163,8 +163,8 @@ static void BM_SQLite_Insert(benchmark::State& state) {
163163}
164164BENCHMARK (BM_SQLite_Insert);
165165
166- // --- Benchmark 3: cloudSQL Sequential Scan ---
167- static void BM_CloudSQL_Scan (benchmark::State& state) {
166+ // --- Benchmark 3: cloudSQL Sequential Scan (Materialized Tuple) ---
167+ static void BM_CloudSQL_ScanMaterialized (benchmark::State& state) {
168168 const int num_rows = state.range (0 );
169169 CloudSQLContext ctx (" ./bench_cloudsql_scan_" + std::to_string (state.thread_index ()));
170170
@@ -203,7 +203,57 @@ static void BM_CloudSQL_Scan(benchmark::State& state) {
203203 }
204204 state.SetItemsProcessed (state.iterations () * num_rows);
205205}
206- BENCHMARK (BM_CloudSQL_Scan)->Arg(1000 )->Arg(10000 );
206+ BENCHMARK (BM_CloudSQL_ScanMaterialized)->Arg(1000 )->Arg(10000 );
207+ // --- Benchmark 3.5: cloudSQL Sequential Scan (Zero-Allocation TupleView) ---
208+ static void BM_CloudSQL_ScanView (benchmark::State& state) {
209+ const int num_rows = state.range (0 );
210+ CloudSQLContext ctx (" ./bench_cloudsql_scanview_" + std::to_string (state.thread_index ()));
211+
212+ for (int i = 0 ; i < num_rows; ++i) {
213+ ctx.executor ->execute (*ParseSQL (
214+ " INSERT INTO bench_table VALUES (" + std::to_string (i) + " , 1.1, 'data');" ));
215+ }
216+
217+ auto parsed_base = ParseSQL (" SELECT * FROM bench_table" );
218+ if (!parsed_base || parsed_base->type () != parser::StmtType::Select) {
219+ state.SkipWithError (" Failed to parse SELECT statement" );
220+ return ;
221+ }
222+ auto select_stmt = std::unique_ptr<parser::SelectStatement>(
223+ static_cast <parser::SelectStatement*>(parsed_base.release ()));
224+
225+ auto root = ctx.executor ->build_plan (*select_stmt, nullptr );
226+ if (!root) {
227+ state.SkipWithError (" Failed to build execution plan" );
228+ return ;
229+ }
230+ root->set_memory_resource (&ctx.executor ->arena ());
231+
232+ for (auto _ : state) {
233+ if (!root->init () || !root->open ()) {
234+ state.SkipWithError (" Failed to open plan" );
235+ return ;
236+ }
237+ cloudsql::storage::HeapTable::TupleView view;
238+ size_t count = 0 ;
239+ while (root->next_view (view)) {
240+ benchmark::DoNotOptimize (view);
241+ count++;
242+ }
243+ if (count != num_rows) {
244+ std::string msg = " Row count mismatch in ScanView: expected " + std::to_string (num_rows) + " , got " + std::to_string (count);
245+ // Print it for debugging
246+ std::cerr << msg << std::endl;
247+ state.SkipWithError (msg.c_str ());
248+ return ;
249+ }
250+ root->close ();
251+ ctx.executor ->arena ().reset ();
252+ }
253+ state.SetItemsProcessed (state.iterations () * num_rows);
254+ }
255+ BENCHMARK (BM_CloudSQL_ScanView)->Arg(1000 )->Arg(10000 );
256+
207257
208258// --- Benchmark 4: SQLite Sequential Scan ---
209259static void BM_SQLite_Scan (benchmark::State& state) {
0 commit comments