Hi!
AutoComplete for empty string '' (I mean, when I precc Ctrl+Space in memo) works noticebly slow (everything pauses on several seconds), especially when editing unit with a form.
There are 2 cases to see how slow it is:
1) Press Ctrl+Space on a new line (wait for... wait... wait... wait few more seconds) finally see AutoComplete box
2) Type: "M" and then press Ctrl+Space (autocomplete box will appear relatively faster, displaying all the items that start with M). Now press Backspace to delete "M" and prepare to wait. This one is especially annoying as it happens while typing and when you don't expect for everything to freeze.
I traced into autocomplete code and found out that most of the time is eaten by TScripterCodeInsight.FillAllMatchingItems routine.
(FScript.Scripter.DefaultInstances.Count in my case contains about 50 units)
As I see in TMS code there's a plenty of room to optimization.
For example TScripterCodeInsight.FillMatchingItems do a lot of repeating job, and can be optimized a little bit.
1) there's a lot of calls to UpperCase(AName) in loops, which should be performed only once
2) all the properties and methods are accessed by index at least 3 times in a loop (this number can be reduced to 1) (and, yes, compiler is not that clever to do that job for you)
These trivial optimizations can give a huge boost in performance.
Original:
procedure TScripterCodeInsight.FillMatchingItems(AClass: TatClass; AName: string; AList: TStrings);varc: integer;beginif AClass = nil thenexit;{ try go into the class based on the name passed }with AClass dobegin{ Since it's final node, search for a partial name }for c := 0 to AClass.Properties.Count - 1 doif Copy(UpperCase(AClass.Properties[c].Name), 1, Length(AName)) = UpperCase(AName) thenAddItemToList(AList, AClass.FName, AClass.Properties[c].Name, AClass.Properties[c]);for c := 0 to AClass.Methods.Count - 1 doif Copy(UpperCase(AClass.Methods[c].Name), 1, Length(AName)) = UpperCase(AName) thenAddItemToList(AList, AClass.FName, AClass.Methods[c].Name, AClass.Methods[c]);end;end;
Optimized v1:
procedure TScripterCodeInsight.FillMatchingItems(AClass: TatClass; AName: string; AList: TStrings);varc: integer;tmpUpperName: string;tmpNameLen: Integer;tmpProp: TatProperty;tmpMeth: TatMethod;beginif AClass = nil thenexit;tmpUpperName := UpperCase(AName);tmpNameLen := Length(AName);{ try go into the class based on the name passed }with AClass dobegin{ Since it's final node, search for a partial name }for c := 0 to AClass.Properties.Count - 1 dobegintmpProp := AClass.Properties[c];if Copy(UpperCase(tmpProp.Name), 1, tmpNameLen) = tmpUpperName thenAddItemToList(AList, AClass.FName, tmpProp.Name, tmpProp);end;for c := 0 to AClass.Methods.Count - 1 dobegintmpMeth := AClass.Methods[c];if Copy(UpperCase(tmpMeth.Name), 1, tmpNameLen) = tmpUpperName thenAddItemToList(AList, AClass.FName, tmpMeth.Name, tmpMeth);end;end;end;
I'm using v6.5.2