The following program illustrates the issue:
Makefile:
CFLAGS = -O3 -std=c++0x
LDFLAGS = -lreadline
test: test.o
g++ $(CFLAGS) $< $(LDFLAGS) -o $@
test.o: test.cpp Makefile
g++ $(CFLAGS) -c $<
test.cpp:
#include <fnmatch.h>
#include <readline/readline.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
static double time()
{
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return ts.tv_sec + (1e-9 * (double)ts.tv_nsec);
}
static void time_fnmatch()
{
for (int i = 0; i < 2; i++)
{
double t = time();
for (int i = 0; i < 1000000; i++)
{
fnmatch("*.o", "testfile", FNM_PERIOD);
}
fprintf(stderr, "%f\n", time()-t);
}
}
int main()
{
time_fnmatch();
char *input = readline("> ");
free(input);
time_fnmatch();
}
Output:
0.045371
0.044537
>
0.185246
0.181607
Before calling readline(), the fnmatch calls are about 4x faster. Although this performance difference is worrying, I'm most interested in finding out what exactly the readline() call might be doing to the program state that would have this effect on other library calls.
Just a guess: readline
initialization probably calls setlocale
.
When a program starts up, it is in the C
locale; a call to setlocale(LC_ALL, "")
will enable the default locale, and these days, the default locale usually uses UTF-8, in which case many string operations become more complex. (Even just iterating over a string.)