case insensitive Pos

smartins picture smartins · Oct 10, 2009 · Viewed 20.8k times · Source

Is there any comparable function like Pos that is not case-sensitive in D2010 (unicode)?

I know I can use Pos(AnsiUpperCase(FindString), AnsiUpperCase(SourceString)) but that adds a lot of processing time by converting the strings to uppercase every time the function is called.

For example, on a 1000000 loop, Pos takes 78ms while converting to uppercase takes 764ms.

str1 := 'dfkfkL%&/s"#<.676505';
  for i := 0 to 1000000 do
    PosEx('#<.', str1, 1); // Takes 78ms

  for i := 0 to 1000000 do
    PosEx(AnsiUpperCase('#<.'), AnsiUpperCase(str1), 1); // Takes 764ms

I know that to improve the performance of this specific example I can convert the strings to uppercase first before the loop, but the reason why I'm looking to have a Pos-like function that is not case-sensitive is to replace one from FastStrings. All the strings I'll be using Pos for will be different so I will need to convert each and every one to uppercase.

Is there any other function that might be faster than Pos + convert the strings to uppercase?

Answer

Jeroen Wiert Pluimers picture Jeroen Wiert Pluimers · Oct 11, 2009

The built-in Delphi function to do that is in both the AnsiStrings.ContainsText for AnsiStrings and StrUtils.ContainsText for Unicode strings.

In the background however, they use logic very similar to your logic.

No matter in which library, functions like that will always be slow: especially to be as compatible with Unicode as possible, they need to have quite a lot of overhead. And since they are inside the loop, that costs a lot.

The only way to circumvent that overhead, is to do those conversions outside the loop as much as possible.

So: follow your own suggestion, and you have a really good solution.

--jeroen