-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[v1.1] Optimize a simple ':', 'true', 'false', 'break', 'continue'
The following idioms are commonly used to create infinite loops: while :; do ... while true; do ... until false; do ... In some scripts, that ':', 'true' or 'false' command may be run millions of time as the loop body does some sort of calculation until a condition is met that triggers a break from the loop. Currently, those dummy commands have to go through the whole sh_exec() rigmarole including sigsetjmp, etc. only to call a builtin that does nothing but return a status value of 0 or 1. If the dummy command does not contain arguments with expansions (which may have side effects), assignments, redirections, and is not being traced, then there is an opportunity for optimisation. This commit adds a three-pronged optimisation approach, hopefully without introducing regressions; please test. src/cmd/ksh93/sh/xec.c: sh_exec(): - Refactor initialisation to make the first optimisation possible. - First optimisation: At the start, optimize a simple literal ':', 'true', 'false', 'break', or 'continue' if possible: * type==TCOM, this means a simple command with only literal arguments, if any (no expansions as the COMSCAN bit is not set) * For 'break' and 'continue': no arguments given at all * No variable assignments list * No I/O redirections * xtrace option not active * DEBUG trap not active * For 'false': errexit option and ERR trap not active For 'false' and 'break/continue', execute very fast simplified versions. For 'true' and ':', there is simply nothing to do. - Second optimisation: case TCOM: In case the previous optimisation could not be applied, add a fallback optimisaton for ':', 'true' and 'false' (e.g., in case there were arguments containing expansions). This doesn't gain as much, but it's still worth avoiding the sigsetjmp which is relatively expensive. This can be done if there are no redirections or arguments. - Third optimisation: case TWH: For a simple 'while :', 'while true' or 'until false', skip doing the recursive sh_exec() call. Set an always_true flag if the condition is always going to be true (and no expansions, assignments, redirections, xtrace, or DEBUG trap exist). - case TFUN: Set the sh.dont_optimize_builtins flag (disabling all the optimizations above) if the user sets a shell function called 'true', 'false', 'break' or 'continue'. This approach might be a bit crude, but the use case is rare, and the optimisation is nonessential, so I think it's not worth refining further. On my system and default compiler flags (-Os), the following loop: typeset -i i; time while true; do ((++i<10000000))||break; done takes 1.0 sec to run before this optimization and 0.6 secs after.
- Loading branch information
Showing
5 changed files
with
89 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters