During the last few weeks I have an interesting discussion on linkedin about my post on trim function()
It was a great discussion, and we came to 5 different implementations of the same function. We also made some performance tests to compare the different implementations. The test we made it is not very accurate and don't cover all cases, it is just to have some timings about the functions.
Here you are the code for the 5 functions:
char *trim_San(register char *s) {
register char *c;
register char *trimedLineStart;
for (c = s; *c && isspace(*c); c++) ;
if (!*c) return c;
trimedLineStart = c++;
c = c + (strlen(c)) – 1;
for (; c>trimedLineStart && isspace(*c); c–) ;
*(++c) = '\0';
c = s;
for (; *trimedLineStart; *c++ = *trimedLineStart++);
*c = 0;
return s;
}
char *trim_Mika(register char *s) {
register char *c;
for (c = s + strlen(s) – 1; c >= s && isspace(*c); *c– = '\0') ;
for (c = s; *c && isspace(*c); c++) ;
char *cc=s;
for (; *c; *cc++ = *c++);
*cc = 0;
return s;
}
char *trim_Mika2(register char *s) {
register char *c = s + strlen(s);
while (isspace(*–c) && s < c)
;
*++c = '\0';
while (isspace(*s++))
;
return s-1;
}
char *trim_Luigi(register char *str)
{
size_t len = 0;
register char *frontp = str – 1;
register char *endp = NULL;
if(str==NULL)
return NULL;
if(str[0]=='\0')
return str;
len = strlen(str);
endp = str + len;
/* Move the front and back pointers to address the first non-whitespace characters from
* each end.
*/
while(isspace(*(++frontp)))
;
while(isspace(*(–endp)) && endp!=frontp)
;
if(str+len-1!=endp)
{
*(endp + 1) = '\0';
}
else if(frontp!=str && endp==frontp)
{
*str = '\0';
}
/* Shift the string so that it starts at str so that if it's dynamically allocated, we can
* still free it on the returned pointer. Note the reuse of endp to mean the front of the
* string buffer now.
*/
endp = str;
if(frontp!=str)
{
while(*frontp)
{
*endp++ = *frontp++;
}
*endp = '\0';
}
return str;
}
char *trim_Jurij(register char *s )
{
int i;
for( i=0; s[i]!='\0' && isspace(s[i]); i++)
;
if( s[i]=='\0' )
{
s[0]='\0';
return s;
}
int k=0,last_w;
do {
for(; s[i]!='\0' && !isspace(s[i]); i++)
{
s[k++] = s[i];
last_w = k;
}
if( s[i] != '\0' )
{
last_w = k;
for(; s[i]!='\0' && isspace(s[i]); i++)
s[k++] = s[i];
}
}
while( s[i] != '\0' );
if( last_w < k )
s[ last_w ] = '\0';
else
s[k] = '\0';
return s;
}
And here you will find the complete source code for tests main.c
Just compile it using the following command
cc -o main main.c
and then run it:
./main
The result, on my Mac Mini with Core 2 Duo 2.26GHz with 8BG of RAM, are the following:
Source string = hggggggggggggg ggggg ggggggggggg
trimmed: >hggggggggggggg ggggg ggggggggggg<
time elapsed = 6 secs and 888185 usecs -- trim_Luigi()
Source string = hggggggggggggg ggggg ggggggggggg
trimmed: >hggggggggggggg ggggg ggggggggggg<
time elapsed = 12 secs and 466838 usecs --trim_Jurij
Source string = hggggggggggggg ggggg ggggggggggg
trimmed: >hggggggggggggg ggggg ggggggggggg<
time elapsed = 7 secs and 772674 usecs --trim_Mika
Source string = hggggggggggggg ggggg ggggggggggg
trimmed: >hggggggggggggg ggggg ggggggggggg<
time elapsed = 5 secs and 637184 usecs --trim_Mika2
Source string = hggggggggggggg ggggg ggggggggggg
trimmed: >hggggggggggggg ggggg ggggggggggg<
time elapsed = 7 secs and 504659 usecs --trim_San
And, what are the results on your PC's?
Gg1
You can also try different strings:
#define LINE " hggggggggggggg ggggg ggggggggggg "
#define LINE " hggggggggggggg ggggg ggggggggggg i"
#define LINE " i hggggggggggggg ggggg ggggggggggg "
#define LINE "i hggggggggggggg ggggg ggggggggggg i"
#define LINE "i hggggggggggggg ggggg ggggggggggg i "
#define LINE " i hggggggggggggg ggggg ggggggggggg i "
#define LINE " "