Skip to content

Turbo Mode

Turbo mode rewrites the trailing portion of a pipeline as native in-process operations, eliminating fork()/execvp() overhead. Instead of spawning separate processes for sort, grep, head, etc., lash executes them as built-in method calls on the line stream.

# What you type:
cat server.log | sort | grep "ERROR" | head -20
# What turbo executes internally:
`cat server.log`.sort().grep("ERROR").take(20)

The leading command (cat server.log) still runs as an external process. Only the recognized trailing commands are converted to native operations.

Terminal window
# interactive session
lash --turbo
# single command
lash --turbo -c "cat log.txt | sort | uniq | head -50"
# script
lash --turbo script.lash

Toggle at runtime:

set turbo on
set turbo off

When active, the powerline prompt displays a TURBO indicator.

Turbo mode recognizes these commands and their common flags:

CommandTurbo Equivalent
sort.sort()
sort -n.sortNumeric()
sort -r.sort().reverse()
sort -rn.sortNumeric().reverse()
grep PATTERN.grep("PATTERN")
grep -v PATTERN.grep(!"PATTERN")
head -n N.take(N)
tail -n N.last(N)
uniq.unique()
tac.reverse()
wc -l.length
cut -dSEP -fN.column(N, "SEP")
revstring reverse per line
trcharacter translation
catpassthrough (stripped)

Commands with unrecognized flags, I/O redirects, or complex argument patterns are left as external processes. Background pipelines (&) are never transformed.

Turbo mode walks the pipeline right-to-left, converting recognized commands into TurboOp operations. The walk stops at the first unrecognized command. Everything to the left becomes the base pipeline executed as normal external processes.

# Full conversion:
sort | grep "TODO" | head -5
# -> all three converted, stdin is the base
# Partial conversion:
custom_tool | sort | grep "err" | head -10
# -> custom_tool runs as external process
# -> sort, grep, head converted to native ops

Only the trailing recognized portion is converted. The remaining prefix commands run as standard external processes.

Turbo mode detects common multi-command patterns and fuses them into single optimized operations:

PatternOptimization
grep PATTERN | head -NStop after N matches (no full scan)
grep PATTERN | tail -NKeep last N matches in ring buffer
grep PATTERN | wc -lCount matches without materializing lines

Fused operations avoid intermediate allocations. grep | wc -l counts matching lines without storing them — it increments a counter for each match and outputs the total.

cat in the middle of a pipeline is a no-op. Turbo mode strips it entirely:

cat file.txt | cat | sort | cat | head -5
# -> `cat file.txt`.sort().take(5)

Standard numeric sort parses numbers in the comparator, costing O(N log N) parse operations. Turbo mode pre-computes numeric keys in O(N), then sorts by pre-computed values:

# turbo sorts this efficiently even with millions of lines
cat measurements.txt | sort -n

When wc -l is the terminal command, turbo mode counts lines as they arrive without storing them. Constant memory regardless of input size.

Turbo mode uses C’s strtod instead of D’s to!double for numeric conversions. This avoids exception overhead on parse failures, which matters when processing large datasets with mixed content.

The ! prefix inverts matches in filter() and grep():

`ls`.filter(!"*.json") # exclude .json files
`cat app.log`.grep(!"DEBUG") # exclude DEBUG lines

In turbo mode, grep -v PATTERN is automatically converted to .grep(!"PATTERN").

  • Short pipelines with common operationssort, grep, head, tail, uniq — where process startup is a significant fraction of total time.
  • Small-to-medium datasets where fork()/execvp() overhead dominates actual computation.
  • Loops that run pipelines repeatedly, where fork overhead accumulates across iterations.

For very large datasets where the actual computation dominates, turbo mode still helps but the relative speedup is smaller.

  • Only recognized commands with supported flag combinations are converted.
  • Commands with I/O redirects (>, >>, <) are left as external processes.
  • Background pipelines (&) are never transformed.
  • Complex argument patterns (e.g., grep -E "pattern1|pattern2" --include="*.log") may not be recognized.