C ++ if语句顺序

时间:2016-09-13 10:06:25

标签: c++ performance search c-strings

程序的一部分需要在搜索有序列表时检查两个c字符串是否相同(例如@dimen/custom_switcher_circle_size)。列表可能会变得非常大,因此速度的小幅提升值得降低可读性。假设您仅限于C ++(请不要建议切换到汇编)。如何改进?

{"AAA", "AAB", "ABA", "CLL", "CLZ"}

您可以假设typedef char StringC[5]; void compare (const StringC stringX, const StringC stringY) { // use a variable so compareResult won't have to be computed twice int compareResult = strcmp(stringX, stringY); if (compareResult < 0) // roughly 50% chance of being true, so check this first { // no match. repeat with a 'lower' value string compare(stringX, getLowerString() ); } else if (compareResult > 0) // roughly 49% chance of being true, so check this next { // no match. repeat with a 'higher' value string compare(stringX, getHigherString() ); } else // roughly 1% chance of being true, so check this last { // match reportMatch(stringY); } } stringX的长度始终相同,并且您不会收到任何无效的数据输入。

根据我的理解,编译器会生成代码,以便CPU检查第一个if语句并跳转,如果它是假的,那么最好是第一个语句最可能是真的,如跳转干扰管道。我还听说在进行比较时,[英特尔] CPU会进行减法并查看标志的状态而不保存减法的结果。有没有办法做stringY一次,而不将结果保存到变量中,但仍然可以在前两个if语句中检查结果?

3 个答案:

答案 0 :(得分:3)

std::binary_search可能会有所帮助:

bool cstring_less(const char (&lhs)[4], const char (&rhs)[4])
{
    return std::lexicographical_compare(std::begin(lhs), std::end(lhs),
                                        std::begin(rhs), std::end(rhs));
}

int main(int, char**)
{
    const char cstrings[][4] = {"AAA", "AAB", "ABA", "CLL", "CLZ"};
    const char lookFor[][4] = {"BBB", "ABA", "CLS"};

    for (const auto& s : lookFor)
    {
        if (std::binary_search(std::begin(cstrings), std::end(cstrings),
                               s, cstring_less))
        {
            std::cout << s << " Found.\n";
        }
    }
}

Demo

答案 1 :(得分:0)

我认为使用哈希表可以大大提高比较速度。此外,如果您的程序是多线程的,您可以在intel线程构建块库中找到一些有用的哈希表。例如,tbb :: concurrent_unordered_map与std :: unordered_map具有相同的api

我希望它可以帮到你。

答案 2 :(得分:0)

如果您尝试将所有字符串相互比较,则会遇到O(N*(N-1))问题。最好的事情,正如您所说的那样,列表可能会变大,就是对它们进行排序(qsort算法有O(N*log(N)),然后将每个元素与列表中的下一个元素进行比较,添加了一个新的O(N),总计O(N*log(N))总复杂度。当你有已经订购的列表时,你可以遍历它(制作事物O(N)),将每个元素与下一个元素进行比较。一个在C和C ++中有效的例子如下:

for(i = 0; i < N-1; i++)  /* one comparison less than the number of elements */
    if (strcmp(array[i], array[i+1]) == 0) 
        break;
if (i < N-1) {  /* this is a premature exit from the loop, so we found a match */
    /* found a match, array[i] equals array[i+1] */
} else { /* we exhausted al comparisons and got out normally from the loop */
    /* no match found */
}