RTL data structure of Delphi runtime library
Colleagues, one section a day, the water flows...
sequence
Most of them are stored in System.Classes and System.Generics.Collection units, which can greatly simplify daily work.
It is a class specifically designed to store and retrieve data.
Every data structure in the world seeks a balance between four different types of data processing: modify data, insert data, search for data, and delete data. Some data structures are good in some fields, and some are good in other fields. However, there is no data structure in this world that can make all the above four operations independent of the size of the data (records, etc.), and cannot be Under this kind of data growth trend, the above 4 kinds of data processing are guaranteed to achieve the same excellent performance.
When designing a program, we should know what our needs are. This will help us choose the appropriate data structure for the design of the program.
Delphi can be used to handle the performance of the data structure of the string
案例:github\Delphi-High-Performance\Chapter 1\RandomWordSearch.dproj
data structure | Operations on data | Big O average time complexity | Worst case | Remarks |
TStringList | Direct Access | O (1) | TStringList provides two working modes: unsorted and sorted, the former is the default. | |
Add | O(1)/O(log n) | In unsorted mode , it can have very good performance; otherwise, it will be very bad | ||
Insert | O (1) | |||
Delete | O (1) | |||
IndexOf | O(n)/O(log n) | Dichotomy: Find the position of the index; in the ordered mode, it is the most suitable dichotomy. | ||
Sort | O(n log n) | In sorting mode , it can have very good performance; otherwise, it will be very bad: because it first sets IndexOf to find the position. | ||
TDictionary | Direct Access | No direct access, only indirect methods can be used to traverse elements | 1. TDictionary cannot access the element TDictionary[i] in this way; it can only traverse the elements in a way similar to for in do; 2. Another limitation of TDictionary: it does not preserve the order in which elements are added |
|
Add | O (1) | O (n) | O(n) only occurs on specially customized data sets, which is not easy to encounter in practical applications. | |
Remove | O (1) | O (n) | O(n) only occurs on specially customized data sets, which is not easy to encounter in practical applications. | |
TryGetValue | O (1) | O (n) | 1. Excellent performance. O(n) only occurs on specially customized data sets, which is not easy to encounter in practical applications. 2. TDictionary always stores the key and value of [pair]. Because if not with any particular key associated with the value of the data, only the key words (Delphi does not allow us to ignore the value part), we can order the code so the value is defined as a Boolean value , and always set it to True. |
|
ContainsKey | O (1) | O (n) | Excellent performance. O(n) only occurs on specially customized data sets, which is not easy to encounter in practical applications. | |
ContainsValue | O (1) | Excellent performance | ||
summary | The O(n) algorithm (such as the unsorted list in this example ) runs much slower than the O(log n) algorithm (such as the sorted list in this example ), while the O(1) algorithm (such as the TDictionary dictionary in this example ) It is the fastest of the above algorithms. |
procedure TfrmRandomWordSearch.LoadWords(wordList: TStringList);
var
word: string;
begin
//:将英语单词数据库中的所有单词加载到内部数据结构中。
//资料来源:https://github.com/dwyl/english-words。
//数据库版权所有:infochimps
FWordsUnsorted := TStringList.Create;
FWordsUnsorted.Assign(wordList);
//:未排序列表:您将看到,生成一个新单词通常需要几百毫秒到几秒钟。
//:由于进程是随机的,并且依赖于 CPU 速度
FWordsSorted := TStringList.Create;
FWordsSorted.Assign(wordList);
FWordsSorted.Sorted := True;
//:排序列表:单词将计算得比“未排序列表”快得多。
FWordsDictionary
:= TDictionary<string,boolean>.Create(wordList.Count);
for word in wordList do
FWordsDictionary.Add(word, True);
//:而TDictionary方法在100毫秒内就能找到一个新词,
//:它比“排序列表”和“未排序列表”快得多。
end;
procedure TfrmRandomWordSearch.FindGoodWord(
const wordTest: TWordCheckDelegate);
var
word: string;
isWordOK: boolean;
time: TStopwatch;
begin
time := TStopwatch.StartNew;
repeat
word := GenerateWord;
isWordOK := wordTest(word);
until isWordOK or (time.ElapsedMilliseconds > 10000);
//:随机提取不同长度的单词(10秒即为超时)
if isWordOK then
lbWords.ItemIndex
:= lbWords.Items.Add(
Format('%s (%d ms)',
[word, time.ElapsedMilliseconds] )
)
else
lbWords.ItemIndex := lbWords.Items.Add('timeout');
end;
Although the algorithm and its time complexity are useful, it will not help in any situation. Sometimes you have used the best algorithm, but your program is still too slow. In this case, you should find the slow parts of the program and use any possible techniques to speed them up. To do this, you must find them first. For example: slow, where is the slowness, is it slower in Add, or slower in Sort, etc.