Ivan Prodanov
Ivan Prodanov

Reputation: 35502

The fastest way to compare a partial string?

I have to compare a partial string "SKILL_______EU_______WAND_______CLERIC_______BASE_____01" with "SKILL".It's meant to check if the first four characters are "SKILL".or the first character only,optimization is needed here!

My problems:

  1. I don't know how to do an optimized comparison.
  2. It has to be repeated 35 000 times so it must be something very fast.

Thanks!

Upvotes: 3

Views: 7625

Answers (10)

Mobius1
Mobius1

Reputation: 1

if AnsiPos('SKILL', 'SKILL_______EU_______WAND_______CLERIC_______BASE_____01') > 0 then

I think that this should do the job, I don't know about the speed of AnsiPos, if its fast or slow or whatever. It works for me whenever I wanna compare pieces of a string. AnsiPos() returns an integer value which represents the start index of the string that you're looking for.

Upvotes: 0

Gerry Coll
Gerry Coll

Reputation: 5975

Use StrUtils.AnsiStartsStr for case-sensitive, StrUtils.AnsiStartsText for case-insensitive (add StrUtils to your uses clause)

Upvotes: 14

Henk Holterman
Henk Holterman

Reputation: 273179

If you really want the best speed you will have to write a little StartsWith function yourself.

// untested, case-sensitive
Function StartsWith(const find, text : string) : Boolean;
var i, len : integer;
begin
   result := true;
   len := Min(Length(find), Length(text));
   For i := 1 to len do
   Begin
     if (find[i] <> text[i]) 
     then begin
       result := False;
       break;
     end;
   End;   
end;

Upvotes: 5

mat
mat

Reputation: 379

No matter which solution you choose please keep in mind to actually test and benchmark it against your current implementation.

Otherwise you are just guessing, not optimizing.

And be aware that premature optimization is the root of all evil.

Good luck!

Upvotes: 2

Re0sless
Re0sless

Reputation: 10886

If you just what to check the first 4/5 characters you could do

i:= Length('SKILL');

LeftStr('SKILL_______EU_______WAND_______CLERIC_______BASE_____01',i) = 'SKILL'

Upvotes: 0

Brian Frost
Brian Frost

Reputation: 13454

Why not do:

function StartsWith( const AMatchStr, ATestStr : string ) : boolean;
begin
  Result := SameText( AMatchStr, copy( ATestStr, 1, Length( AMatchStr ));
end;

This will not process any part of ATestStr beyond your starting text. Bri

Upvotes: 0

Nick Dandoulakis
Nick Dandoulakis

Reputation: 43110

In case you want to check just the 1st character, you can do it like this:

if 'S' = 'SKILL_______EU_______WAND_______CLERIC_______BASE_____01'[1] then
begin
    showmessage('SKILL');
end

Upvotes: 1

Denis Biondic
Denis Biondic

Reputation: 8201

I don't know much about Delphi, but I think (in any language / framework / platform) Regex is the fastest way for string scanning ...

You didn't exactly specify all the conditions you are searching for...

Upvotes: 0

schnaader
schnaader

Reputation: 49719

I think the Delphi routines are quite optimized and fast, so just use them.

var
  position : Integer;

begin
  // AnsiPos
  //   returns the position of a substring in a string
  //   or 0 if the substring isn't found
  position := AnsiPos('SKILL', 'SKILL_______EU_______WAND_______CLERIC_______BASE_____01');
end;

Upvotes: 1

1800 INFORMATION
1800 INFORMATION

Reputation: 135265

35000 repetitions really isn't that much these days, it probably doesn't matter what you do.

Upvotes: 5

Related Questions