// Large-scale bulk-insert / CTE materialization benchmark. // Isolates the SqlBulkInsert Go RTL win: rows × cols boundary // crossings collapse to a single RTL call, so the speedup grows // linearly with N and M. #include "FiveSqlDef.ch" PROCEDURE Main() LOCAL t0, t1, i, aR, nRows ErrorBlock( {|e| QOut( "TRAP: " + e:description + " " + e:operation ), Break(e) } ) ? "================================================================" ? " FiveSql2 Bulk Insert / Large-CTE Benchmark" ? "================================================================" ? SetupLarge() ? "--- CTE materialization at scale ---" /* Big CTE: filter 10,000 rows, materialize, ORDER BY in outer. */ t0 := hb_MilliSeconds() FOR i := 1 TO 20 aR := five_SQL( ; "WITH big_cte AS (SELECT id, name, val FROM bench_big WHERE val > 5000) " + ; "SELECT * FROM big_cte ORDER BY val DESC" ) NEXT t1 := hb_MilliSeconds() nRows := 0 IF ValType( aR ) == "A" .AND. Len( aR ) >= 2 nRows := Len( aR[ 2 ] ) ENDIF R( "BULK_CTE_10k_20iter", t1 - t0, nRows ) /* Subquery-driving-table materialization at scale. */ t0 := hb_MilliSeconds() FOR i := 1 TO 20 aR := five_SQL( ; "SELECT a.id, a.val FROM (SELECT id, val FROM bench_big WHERE val > 8000) a " + ; "ORDER BY a.val" ) NEXT t1 := hb_MilliSeconds() nRows := 0 IF ValType( aR ) == "A" .AND. Len( aR ) >= 2 nRows := Len( aR[ 2 ] ) ENDIF R( "BULK_SUBQ_10k_20iter", t1 - t0, nRows ) CleanupLarge() ? ? "================================================================" RETURN STATIC FUNCTION SetupLarge() LOCAL i IF hb_FileExists( "bench_big.dbf" ) FErase( "bench_big.dbf" ) ENDIF dbCreate( "bench_big.dbf", { ; { "ID", "N", 10, 0 }, ; { "NAME", "C", 30, 0 }, ; { "VAL", "N", 10, 0 } ; } ) USE bench_big.dbf NEW EXCLUSIVE FOR i := 1 TO 10000 dbAppend() FieldPut( 1, i ) FieldPut( 2, "Name_" + PadL( hb_ntos( i ), 6, "0" ) ) FieldPut( 3, i ) NEXT dbCommit() CLOSE bench_big RETURN NIL STATIC FUNCTION CleanupLarge() dbCloseAll() FErase( "bench_big.dbf" ) RETURN NIL STATIC FUNCTION R( cLabel, nMs, nRows ) LOCAL cLine := PadR( cLabel, 28 ) + Str( nMs, 6 ) + " ms" IF nRows > 0 cLine += " rows=" + hb_ntos( nRows ) ENDIF ? " ", cLine RETURN NIL