Finding a string from a text file, from bottom

Viewed 146

I need to find a certain string, in a text file, from bottom (the end of the line). Once the string has been found, the function exit.

Here is my code, which is working fine. But, it is kind of slow. I meant, I run this code every 5 seconds. And it consumes about 0.5% to 1% CPU time. The text file is about 10 MB.

How to speed this up? Like, really fast and it doesn't consume much CPU time.

function TMainForm.GetVMem: string;
var
  TS: TStrings;
  sm: string;
  i: integer;
begin
  TS := TStringList.Create;
  TS.LoadFromFile(LogFileName);
  for i := TS.Count-1 downto 0 do
  begin
    Application.ProcessMessages;
    sm := Trim(TS[i]);
    if Pos('Virtual Memory Total =', sm) > 0 then
    begin
      Result := sm;
      TS.Free;
      exit;
    end;
  end;
  Result := '';
  TS.Free;
end;
1 Answers

You can use a TMemoryStream and use LoadFromFile to load the complete file content.

The you can cast the property Memory to either PChar or PAnsiChar or other character type depending on file content.

When you have the pointer, you can use it to check for content. I would avoid using string handling because it is much slower than pointer operation.

You can move the pointer from the end of memory (use Stream.Size) and search backward for the CR/LF pair (or whatever is used as line delimiter). Then from that point check for the searched string. If found, you are done, if not, loop searching the previous CR/LF.

That is more complex than the method you used but - if done correctly - will be faster.

If the file is to big to fit in memory, specially in a x32 application, you'll have to resort to read the file line by line, keeping only one line, going to the end of file. Each time you find the searched string, then save his position. At the end of file, this saved position - if any - will be the last searched file.

If the file is really very large, and the probability that the searched string is near the end, you may read the file backward (Setting TStream.position to have direct access). block by block. Then is each block, use the previous algorithm. Pay attention that the searched string may be split in two blocks depending on the block size.

Again, depending on the file size, you may split the search in several parallel searches using multi threading. Do not create to much thread neither. Pay attention that the searched string may be split in two blocks assigned to different threads depending on the block size.

Related