From b730874ea117ef8681359fae92825b85a52af401 Mon Sep 17 00:00:00 2001 From: Justin Azoff Date: Tue, 17 Oct 2017 18:45:06 -0400 Subject: [PATCH] problem: for loops over empty tables are slow. This change doubles the performance of for loops over empty tables. A bro binary that prints out this size shows for testing/external/bro-testing/2009-M57-day11-18.trace, for loops are run over tables of size: 11477 for size 0 8371 for size 1 1227 for size 3 239 for size 2 141 for size 6 57 for size 5 10 for size 4 5 for size 7 2 for size 13 2 for size 8 2 for size 11 1 for size 9 ~53% of the for loops were across an empty table. These loops come from things like the for loop in the http script over c$http_state$pending This change prevents the creation of an iteration cookie entirely if the table is empty. Using this test script: const scan_ports: table[port] of count = { }; local x = 0; while ( x < 20000000 ) { for(p in scan_ports) { } ++x; } $ time bro.orig -b ___bench.bro real 0m10.732s user 0m10.415s sys 0m0.113s $ time bro.nocookie -b ___bench.bro real 0m4.694s user 0m4.464s sys 0m0.086s --- src/Stmt.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Stmt.cc b/src/Stmt.cc index d93e8ff14e..ac7bcb39b5 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -1292,6 +1292,8 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const { TableVal* tv = v->AsTableVal(); const PDict(TableEntryVal)* loop_vals = tv->AsTable(); + if (!loop_vals->Length()) + return ret; HashKey* k; IterCookie* c = loop_vals->InitForIteration();