-
Notifications
You must be signed in to change notification settings - Fork 27
Description
This is a follow up to #133, which had some loose ends left by #134.
For one thing, my history file has been growing lately and I've noticed that shell startup time is starting to bog down because of it. This seems to be due to the read_history call to start up the shell. I keep my max-history-length pretty small, but I like to let the file itself grow large; apparently, in cases like that, read_history will do all the work of loading up every history entry in the file, performing gettimeofday syscalls, reallocations, and memmoves in the process. There's a ton of wasted work.
Readline does provide a read_history_range function, but there's no way to tell it to load the last N entries in the file -- only the first N entries. (Given how much else is built around the concept of the last N entries in history, this fact bewilders me.) There is a way to work around this, by manually counting the lines in the history file and using that to produce the arguments to read_history_range. That's a bit fragile, since it would break with history_write_timestamps, but it does speed things up a noticeable amount:
; time es.old -i <<< exit
[subshell]; exit
0.081r 0.012u 0.068s es.old -i
; time es.new -i <<< exit
[subshell]; exit
0.009r 0.008u 0.001s es.new -i
While I was looking at this, I noticed a couple other things as well. The first one is that local (max-history-length = 1) es -c blah eats the current shell's history as well. I think the easiest fix for this would be to make $&setmaxhistorylength do the same "set a flag and update the real state at the next callreadline()" thing that $&sethistory and $&resetterminal do. We could also read in the history file again when increasing max-history-length, but I think that might cause unexpected results in some cases so we might not want that.
The second thing I noticed was that people who might want a completely unbounded history are supposed to use max-history-length = (), but doing that doesn't work very well, because without a value inherited from the environment, subshells will default to the initial.es-given value of 5000. So either we need a set value that means "unlimited", or we need some other solution to this. My vote would probably be to have an explicit unlimited value, in part because that would make it easier to have two-value max-history-lengths which configure in-memory history length AND history file length.