// Large-scale UPDATE benchmark — many matching rows so the per-row // savings of SqlBulkUpdate amortize the PcCompile setup cost. #include "FiveSqlDef.ch" PROCEDURE Main() LOCAL t0, t1, i ErrorBlock( {|e| QOut( "TRAP: " + e:description + " " + e:operation ), Break(e) } ) ? "================================================================" ? " FiveSql2 UPDATE Benchmark (10k rows, many matching)" ? "================================================================" ? SetupLarge() /* Match 2500 rows per UPDATE (val BETWEEN 2500 AND 5000). */ t0 := hb_MilliSeconds() FOR i := 1 TO 50 five_SQL( "UPDATE bench_big SET val = val + 1 WHERE val BETWEEN 2500 AND 5000" ) NEXT t1 := hb_MilliSeconds() R( "UPD_2500match_50iter", t1 - t0 ) /* Match ALL rows (no WHERE). */ t0 := hb_MilliSeconds() FOR i := 1 TO 10 five_SQL( "UPDATE bench_big SET val = val + 0" ) NEXT t1 := hb_MilliSeconds() R( "UPD_all_10iter_10k_each", t1 - t0 ) /* Match 0 rows (WHERE never true). */ t0 := hb_MilliSeconds() FOR i := 1 TO 100 five_SQL( "UPDATE bench_big SET val = val + 1 WHERE val < 0" ) NEXT t1 := hb_MilliSeconds() R( "UPD_0match_100iter", t1 - t0 ) CleanupLarge() ? ? "================================================================" RETURN STATIC PROCEDURE 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, "N_" + PadL( hb_ntos( i ), 6, "0" ) ) FieldPut( 3, i ) NEXT dbCommit() CLOSE bench_big RETURN STATIC PROCEDURE CleanupLarge() dbCloseAll() FErase( "bench_big.dbf" ) RETURN STATIC FUNCTION R( cLabel, nMs ) ? " ", PadR( cLabel, 32 ) + Str( nMs, 7 ) + " ms" RETURN NIL