Performance on the row hot path
A transform’s processRow() runs once per row. At a million rows, anything measured in microseconds is measured in seconds, and code that looks harmless in a dialog becomes the bottleneck.
This page collects what is known about that path, so the same lessons are not relearned one transform at a time.
The shape of the problem
- Work that belongs in
init(), done inprocessRow() -
Resolving variables, looking up field indexes, building formatters, cloning row metadata. The classic mistake is calling something like
getFieldNames()orclone()on the row metadata for every row when the layout has not changed since the first one. - Allocation per row
-
A new object per row is a new object per million rows. Reusing a buffer held in the transform’s data object is usually the fix.
- Logging
-
LogChannelchecks the level before it builds aLogMessage, so a discarded call is cheap on the logging side — but the argument is not.logDebug("row " + rowNr + " of " + total)concatenates on every row whether or not anyone is listening, andBaseMessages.getString(…)does a bundle lookup on every row. Guard those behindisDebug(), and prefer not to log per row at all: a message that does pass the level check is expensive enough to dominate a fast transform.
| This page is a scaffold. Still to write:
|