C++ C++-标记器非常慢

C++ C++-标记器非常慢,c++,C++,我只是不明白我做错了什么。下面显示的unicode标记器函数非常慢。也许有人能给我一个加速的提示? 谢谢你的帮助。顺便说一下,ustring是Glib::ustring。 sep1是不应在结果中显示的分隔符 sep2是分隔符,应该是结果中的单个标记 void tokenize(const ustring & u, const ustring & sep1, const ustring & sep2, vector<ustring> &

我只是不明白我做错了什么。下面显示的unicode标记器函数非常慢。也许有人能给我一个加速的提示? 谢谢你的帮助。顺便说一下,
ustring
Glib::ustring
sep1
是不应在结果中显示的分隔符
sep2
是分隔符,应该是结果中的单个标记

void tokenize(const ustring & u, const ustring & sep1, 
        const ustring & sep2, vector<ustring> & tokens) {
    ustring s;
    s.reserve(100);
    ostringstream os;
    gunichar c;
    for (int i = 0; i < u.length(); i++) {
        c = u[i];
        if (sep1.find(c) != ustring::npos) {
            tokens.push_back(s);
            s = "";
        }
        else if (sep2.find(c) != ustring::npos) {
            tokens.push_back(s);
            s = "";
            s.append(1, c);
            tokens.push_back(s);
            s = "";
        }
        else {
            s.append(1, c);
        }
    }
    if (s!="")
    tokens.push_back(s);
}
void标记化(const-ustring&u、const-ustring&sep1、,
施工图和sep2、矢量和标记){
美国贸易代表团;
s、 储备(100);
ostringstream os;
古尼卡尔c;
对于(int i=0;i
我现在将其更改为(现在介于1到2秒之间):

ustrings;
s、 储备(100);
ostringstream os;
古尼卡尔c;
set_sep1;
int i=0;

对于(i=0;i我认为以下内容将显著加快您的代码速度,但需要做一些工作才能找到答案。目前您是:

  • 迭代u的每个字符
  • 在sep1中进行查找,以查看该字符是否在分隔符中
  • 根据需要一次追加一个字符
  • 假设分隔符列表小于正在分析的字符串,则最好执行以下操作:

  • 对于每个分隔符,查找以查看分隔符是否在字符串中
  • 如果找到,一次性附加整个子字符串,并在剩余的子字符串上进行查找

  • 第二个优化是按照最有可能成功的方式订购分离器。例如,如果为“,”是最常用的分隔符,请确保首先在该分隔符上运行查找。如果一个分隔符比其他分隔符热得多,这将产生很大的差异。

    我认为以下内容将显著加快您的代码速度,但查找起来需要做一些工作。目前您是:

  • 迭代u的每个字符
  • 在sep1中进行查找,以查看该字符是否在分隔符中
  • 根据需要一次追加一个字符
  • 假设分隔符列表小于正在分析的字符串,则最好执行以下操作:

  • 对于每个分隔符,查找以查看分隔符是否在字符串中
  • 如果找到,一次性附加整个子字符串,并在剩余的子字符串上进行查找

  • 第二个优化是按照最有可能成功的方式订购分离器。例如,如果为“,”是最常用的分隔符,请确保首先在该分隔符上运行查找。如果一个分隔符比其他分隔符热得多,这将产生很大的差异。

    我认为以下内容将显著加快您的代码速度,但查找起来需要做一些工作。目前您是:

  • 迭代u的每个字符
  • 在sep1中进行查找,以查看该字符是否在分隔符中
  • 根据需要一次追加一个字符
  • 假设分隔符列表小于正在分析的字符串,则最好执行以下操作:

  • 对于每个分隔符,查找以查看分隔符是否在字符串中
  • 如果找到,一次性附加整个子字符串,并在剩余的子字符串上进行查找

  • 第二个优化是按照最有可能成功的方式订购分离器。例如,如果为“,”是最常用的分隔符,请确保首先在该分隔符上运行查找。如果一个分隔符比其他分隔符热得多,这将产生很大的差异。

    我认为以下内容将显著加快您的代码速度,但查找起来需要做一些工作。目前您是:

  • 迭代u的每个字符
  • 在sep1中进行查找,以查看该字符是否在分隔符中
  • 根据需要一次追加一个字符
  • 假设分隔符列表小于正在分析的字符串,则最好执行以下操作:

  • 对于每个分隔符,查找以查看分隔符是否在字符串中
  • 如果找到,一次性附加整个子字符串,并在剩余的子字符串上进行查找
  • 第二个优化是按照最有可能成功的方式订购分离器。如果例如“,”是最常用的分离器,请确保首先在该分离器上运行查找。如果一个分离器比其他分离器热得多,这将产生很大的差异。

    以下是可能“非常非常慢”的原因:

  • ustring::length()
  • ustring::append()
  • 通过
    操作员[]随机访问
    ustring
    :例如
    c=u[i];
  • 请尝试以下操作:

  • 不要在循环中调用
    u.length()
    ,而是将长度存储在变量中,并在循环中与该变量进行比较
  • 将当前标记的字符附加到
    ostringstream
    wostringstream
    而不是ustring
  • 使用迭代器(而不是涉及随机访问的索引)遍历
    ustring
  • 例如:

    for(ustring::const_iterator it = u.cbegin(); it != u.cend(); it++)
    {
        c = *it;
        //implementation follows
    }
    
    这里可能“非常非常慢”的原因有:

  • ustring::length()
  • ustring::append()
  • 通过
    操作员[]随机访问
    ustring
    :例如
    c=u[i];
  • 请尝试以下操作:

  • 不要在循环中调用
    u.length()
    ,而是将长度存储在变量中,并在循环中与该变量进行比较
  • 将当前标记的字符附加到
    ostringstream
    wostringstream
    而不是ustring
  • 迭代for(ustring::const_iterator it = u.cbegin(); it != u.cend(); it++) { c = *it; //implementation follows }