char* Migrated[]={"026","109"};
int isMigrated(char* codeB)
{
int i;
int n=sizeof(Migrated)/sizeof(*Migrated);
for(i=0;i<n;i++)
{
if(strcmp(Migrated[i],codeB)==0)
return 0;
}
return -1;
}
is this function optimised from execution time perspective ?
Migrated should contain at maximum 200 value all of them are 4 byte .
3 Answers 3
I am not sure how far you intend to expand Migrated
, but something like this could be an optimisation:
char* Migrated[]={"026","109"};
int isMigrated(char* codeB)
{
int i;
// since we know that all strings in Migrated are 4 bytes long
int32_t _codeB_as_int32 = *(int32_t *)codeB;
int32_t * Migrated_as_int32 = Migrated;
for(i=0;
i<sizeof(Migrated)/sizeof(*Migrated); // sizeof is a compile time constant, better to put it here
i++)
{
if(codeB == Migrated_as_int32[i])
return 0;
}
return -1;
}
it all really depends on what you intend to have in Migrated
.
-
\$\begingroup\$ Right now
Migrated
is an array of pointers, so this won't work. You need to redefine it as an array of 4 character arrays. Also, you should probably make surecodeB
is 4 bytes long before converting it to an integer. \$\endgroup\$ughoavgfhw– ughoavgfhw2013年09月09日 16:35:21 +00:00Commented Sep 9, 2013 at 16:35 -
\$\begingroup\$ Don't do this. The compiler will do this for for itself. You just need to write the code such that the compiler can see that that's a valid thing to do. \$\endgroup\$ams– ams2013年09月09日 16:38:44 +00:00Commented Sep 9, 2013 at 16:38
You could assert that any code has to come from the Migrated
array and thus only compare the addresses, i.e. omit the strcmp
call and just test for Migrated[i] == codeB
.
-
1\$\begingroup\$ THe more assumptions you make, the better it gets. If we assume all of the strings are 3 characters long - so 4 with terminating NULL, they be compared as
int
s - and possibly stored in this way too. Probably not practical solution though. \$\endgroup\$Marko– Marko2013年09月09日 15:52:20 +00:00Commented Sep 9, 2013 at 15:52 -
\$\begingroup\$ @Marko: Sure, and if you assume that no given string matches, you could return
-1
right away. ;-) You have to draw a line somewhere. I just picked a more or less random assumption to illustrate that the best potential for optimization is by considering the domain of values fed to the function. \$\endgroup\$Frerich Raabe– Frerich Raabe2013年09月09日 15:59:31 +00:00Commented Sep 9, 2013 at 15:59
If Migrated
is a unchanging list that really is as short as you show then you should just hard-code the strings into the code (or use a macro, or declare them const
(make sure they're const pointers as well as pointers to const)). That way the compiler can optimise the strcmp
calls away to almost nothing; short strings like you show might even be done via a numeric comparison (a four byte string is the same length as a number), but don't do it manually - let the compiler sort that out. The key point is that the compiler cannot optimize this to the maximum if it can't prove that Migrated
is constant.
If Migrated
is unchanging, but much larger than shown, then you should use "perfect hashing". There is a tool called gperf
that, given a list of names, will generate C code to do the lookup in an optimal way.
If Migrated
can change at run-time and is small then you're probably just about optimal already.
If Migrated
can change at run-time, but can be very large then a hash table is the best option. Failing that a sorted, balanced tree would be better than a list.
-
\$\begingroup\$ Does perfect hashing do better than, say, a trie table or an Aho-Corsack automaton for matching a string against other strings? The constant factor of a hash function can be quite high (sometimes linear in the length of the string). \$\endgroup\$sfstewman– sfstewman2013年09月09日 16:40:35 +00:00Commented Sep 9, 2013 at 16:40
-
\$\begingroup\$ @sfstewman: Given this input,
gperf
produces this output. There's not too much computational complexity there. \$\endgroup\$ams– ams2013年09月10日 09:35:09 +00:00Commented Sep 10, 2013 at 9:35 -
\$\begingroup\$ @sfstewman: perfect hashing is for finding one word in a moderate sized dictionary. It's not for finding dictionary words in a corpus of text, like Aho-Corsack seems to be. Trie tables can outperform imperfect hashing, but only in the worst case, and can never outperform a perfect hash table. \$\endgroup\$ams– ams2013年09月10日 09:45:05 +00:00Commented Sep 10, 2013 at 9:45
Migrated
array they yes, it is optimized, but if there are thousands of items then there are better ways to code it. \$\endgroup\$codeB
and based on it compare the string with only one viable item in the array. \$\endgroup\$