Fix pgbench performance issue induced by commit af35fe501.
authorTom Lane <[email protected]>
Fri, 7 Feb 2025 18:41:43 +0000 (13:41 -0500)
committerTom Lane <[email protected]>
Fri, 7 Feb 2025 18:41:43 +0000 (13:41 -0500)
Commit af35fe501 caused "pgbench -i" to emit a '\r' character
for each data row loaded (when stderr is a terminal).
That's effectively invisible on-screen, but it causes the
connected terminal program to consume a lot of cycles.
It's even worse if you're connected over ssh, as the data
then has to pass through the ssh tunnel.

Simplest fix is to move the added logic inside the if-tests
that check whether to print a progress line.  We could do
it another way that avoids duplicating these few lines,
but on the whole this seems the most transparent way to
write it.

Like the previous commit, back-patch to all supported versions.

Reported-by: Andres Freund <[email protected]>
Author: Tom Lane <[email protected]>
Reviewed-by: Nathan Bossart <[email protected]>
Discussion: https://postgr.es/m/4k4drkh7bcmdezq6zbkhp25mnrzpswqi2o75d5uv2eeg3aq6q7@b7kqdmzzwzgb
Backpatch-through: 13

src/bin/pgbench/pgbench.c

index ed301e120c41242a351a2a18a1581fc98820df28..b6c42f65ac04b55e4f5ff3702e073bebbfbf6256 100644 (file)
@@ -3934,6 +3934,16 @@ initGenerateDataClientSide(PGconn *con)
                            j, (int64) naccounts * scale,
                            (int) (((int64) j * 100) / (naccounts * (int64) scale)),
                            elapsed_sec, remaining_sec);
+
+           /*
+            * If the previous progress message is longer than the current
+            * one, add spaces to the current line to fully overwrite any
+            * remaining characters from the previous message.
+            */
+           if (prev_chars > chars)
+               fprintf(stderr, "%*c", prev_chars - chars, ' ');
+           fputc(eol, stderr);
+           prev_chars = chars;
        }
        /* let's not call the timing for each row, but only each 100 rows */
        else if (use_quiet && (j % 100 == 0))
@@ -3951,20 +3961,20 @@ initGenerateDataClientSide(PGconn *con)
                                j, (int64) naccounts * scale,
                                (int) (((int64) j * 100) / (naccounts * (int64) scale)), elapsed_sec, remaining_sec);
 
+               /*
+                * If the previous progress message is longer than the current
+                * one, add spaces to the current line to fully overwrite any
+                * remaining characters from the previous message.
+                */
+               if (prev_chars > chars)
+                   fprintf(stderr, "%*c", prev_chars - chars, ' ');
+               fputc(eol, stderr);
+               prev_chars = chars;
+
                /* skip to the next interval */
                log_interval = (int) ceil(elapsed_sec / LOG_STEP_SECONDS);
            }
        }
-
-       /*
-        * If the previous progress message is longer than the current one,
-        * add spaces to the current line to fully overwrite any remaining
-        * characters from the previous message.
-        */
-       if (prev_chars > chars)
-           fprintf(stderr, "%*c", prev_chars - chars, ' ');
-       fputc(eol, stderr);
-       prev_chars = chars;
    }
 
    if (eol != '\n')