On 9/24/16 2:17 PM, Hubert Schmid wrote:
> Configuration Information [Automatically generated, do not change]:
> Machine: x86_64
> OS: linux-gnu
> Compiler: gcc
> Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
> -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' 
> -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
> -DHAVE_CONFIG_H   -I.  -I../. -I.././include -I.././lib  -Wdate-time 
> -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/bash-31ueiH/bash-4.4=. 
> -fstack-protector-strong -Wformat -Werror=format-security -Wall 
> -Wno-parentheses -Wno-format-security
> uname output: Linux vivo 4.7.0-1-amd64 #1 SMP Debian 4.7.4-2 (2016-09-19) 
> x86_64 GNU/Linux
> Machine Type: x86_64-pc-linux-gnu
> 
> Bash Version: 4.4
> Patch Level: 0
> Release Status: release
> 
> Description:
>       If the history file (`.bash_history`) starts with a timestamp
>       (`HIST_TIMESTAMP_START`), and contains lines that have been written
>       without timestamps, then reading the history file is (a) very slow
>       because (b) consecutive lines without timestamps are merged into a
>       single history entry with quadratic complexity.
> 
>       Apparently, this problem didn't exist in the previous version (4.3).
                [...]
> Fix:
>       Do not set `history_multiline_entries` to a non-zero value in
>       `lib/readline/histfile.c`.
> 
>       Workaround without changing the code: Add a dummy history entry add
>       the beginning of the history file without a timestamp. That has a
>       similar effect as the code change, i.e. multi-line entries are not
>       supported, and consecutive lines without timestamps will not be merged
>       into a line history entry.

Try this patch and see if it improves the situation for this corner case.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    c...@case.edu    http://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.4/lib/readline/history.c	2015-12-28 13:50:31.000000000 -0500
--- lib/readline/history.c	2016-09-30 14:28:40.000000000 -0400
***************
*** 417,426 ****
  {
    HIST_ENTRY *hent;
!   size_t newlen, curlen;
    char *newline;
  
    hent = the_history[which];
    curlen = strlen (hent->line);
!   newlen = curlen + strlen (line) + 2;
    newline = realloc (hent->line, newlen);
    if (newline)
--- 421,441 ----
  {
    HIST_ENTRY *hent;
!   size_t newlen, curlen, minlen;
    char *newline;
  
    hent = the_history[which];
    curlen = strlen (hent->line);
!   minlen = curlen + strlen (line) + 2;	/* min space needed */
!   if (curlen > 256)		/* XXX - for now */
!     {
!       newlen = 512;		/* now realloc in powers of 2 */
!       /* we recalcluate every time; the operations are cheap */
!       while (newlen < minlen)
! 	newlen <<= 1;
!     }
!   else
!     newlen = minlen;
!   /* Assume that realloc returns the same pointer and doesn't try a new
!      alloc/copy if the new size is the same as the one last passed. */
    newline = realloc (hent->line, newlen);
    if (newline)

Reply via email to