【问题标题】:Why does the first call to readline() slow down all subsequent calls to fnmatch()?为什么第一次调用 readline() 会减慢所有后续调用 fnmatch() 的速度?
【发布时间】:2014-08-23 01:20:31
【问题描述】:

以下程序说明了这个问题:

生成文件:

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();
}

输出:

0.045371
0.044537
> 
0.185246
0.181607

在调用 readline() 之前,fnmatch 调用大约快 4 倍。虽然 这种性能差异令人担忧,我最感兴趣的是找出 readline() 调用究竟对程序状态做了什么 会对其他库调用产生这种影响。

【问题讨论】:

    标签: c++ c linux readline glob


    【解决方案1】:

    只是猜测:readline 初始化可能会调用setlocale。

    当程序启动时,它位于C 语言环境中;调用setlocale(LC_ALL, "") 将启用默认语言环境,而现在,默认语言环境通常使用 UTF-8,在这种情况下,许多字符串操作变得更加复杂。 (甚至只是遍历一个字符串。)

    【讨论】:

    • 用 setlocale(LC_ALL, "") 替换 readline() 对运行时有同样的效果 - 很好的猜测。
    • 经过进一步研究,readline() 最终从我系统上环境的 LANG 变量中调用 setlocale(LC_CTYPE, lspec); 和 lspec(参考:readline 6.3 源代码,nls.c)。还可以在 readline.c 的 python 源代码中看到这个有趣的评论:/* GNU readline() mistakenly sets the LC_CTYPE locale. * This is evil. Only the user or the app's main() should do this! * We must save and restore the locale around the rl_initialize() call. */
    • @ajclinto:我同意 Python 包装器中的评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    相关资源
    最近更新 更多