views:

763

answers:

8

Hello,

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!

+3  A: 

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

1800 INFORMATION
Sensible remark, I don't get the downvotes.
Henk Holterman
It is a sensible thought. Do it in the most foolproof way, no matter how slow, then store the results and never do it again.
quillbreaker
Sensible as it may be, it doesn't actually answer the question, whatever the question really is. So I could certainly understand this being voted down.
Rob Kennedy
+2  A: 

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;
schnaader
This will keep on scanning the entire domainstring, even if the 1st chars are unequal.
Henk Holterman
A: 

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...

Sapphire
Regex are very complete, but they are not reputed to be fast at all. You should use regex for complex searches not trivial ones, especially not if speed is of the essence.
Lepidosteus
"not reputed to be fast at all" - do you have a link for that? Most reg-ex are matched in O(n) and very hard to beat with handwritten code.
Henk Holterman
@Henk Holterman: sorry I should have been more specific; fast in case such as the one in this question. If all you want is to check the first 4-5 characters of a string to see if it matches something, you better use functions which are specifically designed and optimized for this.
Lepidosteus
That's why I said that he didn't specify all the conditions!
Sapphire
+1  A: 

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
Nick D
Does that even compile?
Rob Kennedy
of course it compiles. I didn't tested in Delphi 2009, though. I'm sure it'll compile on all Delphi versions.
Nick D
I didn't think it was legal to apply the bracket operator to a string literal. But if you say it compiles, I'll take your word for it. Note that Free Pascal *doesn't* accept that syntax (even in "Delphi mode").
Rob Kennedy
A: 

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

Brian Frost
But it will copy chars, not strictly necessary.
Henk Holterman
Why not do that? Because the library already comes with such a function, and even if it didn't, it would be better to use `StrLComp` than to make a temporary copy of the string.
Rob Kennedy
A: 

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'
Re0sless
+1  A: 

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!

mat
+8  A: 

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

Gerry