[PATCH] Make completions almost instantaneous

Elena Zannoni ezannoni@cygnus.com
Fri Mar 30 13:46:00 GMT 2001


Ok, Approved. Please check it in.  Just to be anal, I ran the
testsuite on solaris w/o seeing any regressions.

Nice catch.

Thanks
Elena


Daniel Berlin writes:
 > Okay, this has pissed me off for years.
 > You accidently hit tab at the wrong time, and boom, you wait forever for
 > completion to tell you it found 7000 symbols.
 > Literally forever (~29 seconds, 16k symbols takes ~1:30. the program i
 > compliled was one line. Real programs end up with *way* too many symbols.
 > I let one sit for 10 minutes before giving up once, because i didn't want
 > to recreate the situation i had gotten to)
 > 
 > This is all due to a "time optimization" performed in completion_list_add_symbol.
 > 
 > Where time optimization is defined as "To save time, increases the order
 > of magnitude of the algorithm by n, even when unncessary"
 > 
 > What the heck am i talking about?
 > 
 > Well, it clips symbols by running through the entire current completion
 > list, maybe twice, comparing the string we are going to insert against
 > them.
 > 
 > That way, we don't insert duplicates.
 > Of course, this is the wrong way to do it (since you get murdered when
 > your list starts getting large, seeing as how you'll do n-1->2n-2 string
 > compares, just to do *one* insertion)  but seeing as how the code was
 > there, I wasted about 2 hours trying to find a faster way to not insert
 > duplicates (binary search the list of completions, for starters, and then
 > do  a sorted insert using binary search again to find the place, and then
 > memmove to  shift the array up, etc) , and then decided to ignore them
 > and do it at the end, since it was obvious it was all the strcmps and
 > moving was almost as expensive in practice, and thus, it would be better
 > to just do it once in a sort, after we had the entire list, and remove the
 > duplicates
 > 
 > But here's the kicker. When i went to go just make it do one sort at the
 > end, and then just not output/remove  the duplicates, i noticed something:
 > readline already does that (remove_duplicate_matches in complete.c, called
 > from postprocess_matches if rl_ignore_completion_duplicates is 1, which it
 > always is for gdb, since we never turn it off)
 > 
 > In other words, all this god damn time is wasted to make sure we don't
 > insert duplicates, and it won't output duplicates *anyway*, because it
 > removes duplicate matches (strangely, using almost exactly the same code i
 > had been ready to add, minus the binary search).
 > 
 > Result:
 > pushing tab twice at the wrong time used to take 1:30 if it
 > geenrated
 > 16k completions (I compiled a very minimal c++, broke on main, ran, and
 > hit "b " tab. I also did the same for "b _" <tab>, which gives me 7k
 > completions).
 > It now takes ~3 seconds.
 > 
 > I'm not joking.
 > 
 > There's obviously no difference in the output, since it was removing
 > duplicates anyway.
 > 
 > No longer do i kill off gdbs because it's faster to re set 15 breakpoints
 > than wait for completion to tell me i screwed up.
 > 
 > 
 > All this patch does is remove code.
 > 
 > Remember kids, premature optimization is the root of all evil.
 > 
 > Since it's unclear to me whether this is an obvious fix, i'll wait for
 > approval from Elena or Jim.
 > 
 > --Dan
 > 
 > 2001-03-30  Daniel Berlin  <dberlin@redhat.com>
 > 
 > 	* symtab.c (completion_list_add_name): Remove duplicate string checks,
 > 	readline already does this, and it's much faster at it, too.
 > 
 > Index: symtab.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/symtab.c,v
 > retrieving revision 1.28
 > diff -c -3 -p -r1.28 symtab.c
 > *** symtab.c	2001/01/30 02:49:36	1.28
 > --- symtab.c	2001/03/30 08:48:30
 > *************** completion_list_add_name (char *symname,
 > *** 2836,2852 ****
 >         return;
 >       }
 > 
 > -   /* Clip any symbol names that we've already considered.  (This is a
 > -      time optimization)  */
 > -
 > -   for (i = 0; i < return_val_index; ++i)
 > -     {
 > -       if (STREQ (symname, return_val[i]))
 > - 	{
 > - 	  return;
 > - 	}
 > -     }
 > -
 >     /* We have a match for a completion, so add SYMNAME to the current list
 >        of matches. Note that the name is moved to freshly malloc'd space. */
 > 
 > --- 2869,2874 ----
 > *************** completion_list_add_name (char *symname,
 > *** 2870,2888 ****
 >   	strncpy (new, word, sym_text - word);
 >   	new[sym_text - word] = '\0';
 >   	strcat (new, symname);
 > -       }
 > -
 > -     /* Recheck for duplicates if we intend to add a modified symbol.  */
 > -     if (word != sym_text)
 > -       {
 > - 	for (i = 0; i < return_val_index; ++i)
 > - 	  {
 > - 	    if (STREQ (new, return_val[i]))
 > - 	      {
 > - 		xfree (new);
 > - 		return;
 > - 	      }
 > - 	  }
 >         }
 > 
 >       if (return_val_index + 3 > return_val_size)
 > --- 2892,2897 ----
 > 



More information about the Gdb-patches mailing list