Сравнение строк C ++ за один такт - PullRequest
12 голосов
/ 15 июля 2009

Можно ли сравнить целые области памяти в одном цикле процессора? Точнее, можно ли сравнить две строки в одном цикле процессора, используя какую-то инструкцию ассемблера MMX? Или strcmp -воплощение уже основано на этой оптимизации?

EDIT: Или же можно поручить компилятору C ++ удалить дубликаты строк, чтобы строки можно было сравнивать просто по их расположению в памяти? Вместо memcmp(a,b) по сравнению a==b (при условии, что a и b являются нативными const char* строками).

Ответы [ 11 ]

0 голосов
/ 15 июля 2009

Вот одно решение, которое использует перечислимые значения вместо строк. Он поддерживает перечисление-значение-наследование и, следовательно, поддерживает сравнение, аналогичное сравнению с подстрокой. Он также использует специальный символ «¤» для именования, чтобы избежать конфликтов имен. Вы можете взять любой класс, функцию или имя переменной и преобразовать его в перечисляемое значение (SomeClassA станет omeSomeClassA).

struct MultiEnum
{
    vector<MultiEnum*> enumList;
    MultiEnum()
    {
        enumList.push_back(this);
    }
    MultiEnum(MultiEnum& base)
    {
        enumList.assign(base.enumList.begin(),base.enumList.end());
        enumList.push_back(this);
    }
    MultiEnum(const MultiEnum* base1,const MultiEnum* base2)
    {
        enumList.assign(base1->enumList.begin(),base1->enumList.end());
        enumList.assign(base2->enumList.begin(),base2->enumList.end());
    }
    bool operator !=(const MultiEnum& other)
    {
        return find(enumList.begin(),enumList.end(),&other)==enumList.end();
    }
    bool operator ==(const MultiEnum& other)
    {
        return find(enumList.begin(),enumList.end(),&other)!=enumList.end();
    }
    bool operator &(const MultiEnum& other)
    {
        return find(enumList.begin(),enumList.end(),&other)!=enumList.end();
    }
    MultiEnum operator|(const MultiEnum& other)
    {
        return MultiEnum(this,&other);
    }
    MultiEnum operator+(const MultiEnum& other)
    {
        return MultiEnum(this,&other);
    }
};

MultiEnum 
    ¤someString,
    ¤someString1(¤someString),  // link to "someString" because it is a substring of "someString1"
    ¤someString2(¤someString);


void Test()
{
    MultiEnum a = ¤someString1|¤someString2;
    MultiEnum b = ¤someString1;

    if(a!=¤someString2){}
    if(b==¤someString2){}
    if(b&¤someString2){}
    if(b&¤someString){}  // will result in true, because someString is substring of someString1
}

PS. У меня определенно было слишком много свободного времени этим утром, но изобретать велосипед иногда было слишком весело ...:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...