c - 意外的循环运行时间

标签 c performance for-loop gcc runtime

我正在编写侧信道攻击演示。我期望进行简单的逐字符检查并提前返回,以便对第一个不正确的字符采取线性比例的时间。例如,如果我有密码 password 并输入 qassword (第一个字母错误)和 passwore (最后一个字母错误),我期望qasswordpasswore 花费的时间更少(因为它在第一个错误的字母时提前退出)。

有问题的循环是:

for (int i = 0; i < 26; i++) {
    if (a[i] != in[i]) {
        return 1;
    }
}
return 1;

我已使用 -O0 禁用优化。

完整代码的输出是:

Diff(9326)
Diff(2)
Diff(1)
Diff(9292)

这让我感到惊讶,因为第一种情况是检查所有字母(好吧,应该花费最长的时间),第二种情况是检查除最后​​一个字母之外的所有字母(应该与第一种情况花费大约相同的时间? ),最后一个案例应该只检查第一个字母(好的,花费最少的时间)。

我的问题是,为什么在完全正确的情况下需要这么长的时间,而在所有其他情况下却需要这么快的时间(即使中间有错误的字母)?

完整代码为( Try It Online ):

#include <stdio.h>
#include <time.h>

int check(char* in) {
    const char* a = "abcdefghijklmnopqrstuvwxyz";

    for (int j = 0; j < 100000; j++) {
        for (int i = 0; i < 26; i++) {
            if (a[i] != in[i]) {
                return 1;
            }
        }
    }

    return 1;
}

int main() {
    clock_t start;
    clock_t diff;

    // All correct
    start = clock();
    check("abcdefghijklmnopqrstuvwxyz");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);

    // Last letter wrong
    start = clock();
    check("abcdefghijklmnopqrstuvwxya");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);

    // First letter wrong
    start = clock();
    check("zbcdefghijklmnopqrstuvwxyz");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);

    // Check if cache issue (same as case 1)
    start = clock();
    check("abcdefghijklmnopqrstuvwxyz");
    diff = clock() - start;

    printf("Diff(%ld)\n", diff);
}

最佳答案

问题出在你的代码中。如果所有字符都匹配,则会检查 100000 次。但是,如果任何一个字符不匹配,那么您将从第一次迭代本身的循环中返回。因此,当所有字符都不匹配时,时间差异很小。

在 if block 中放置一个 break 语句,而不是 return

        for (int j = 0; j < 100000; j++) {
                 for (int i = 0; i < 26; i++) {
                     if (a[i] != in[i]) {
                         break;
                     }
                  }
        }

关于c - 意外的循环运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58619121/

相关文章:

c - 从 C 程序将 sqlite3 表导出到文本文件

MySQL 为什么在有索引时记录为慢查询/日志查询不使用索引?

c++ - for 在没有收到命令时如何行动?

c - C 程序中的段错误(核心转储)

C 客户端只能连接到 localhost。

c - 尝试混合某些字符串时出现意外的段错误

Android 拼图游戏 - Native 与 Phonegap

JavaScript:为什么原生 Array.prototype.map 比 Chrome 控制台中的 for 循环更快?

python - 如何迭代 pandas 数据帧行,查找字符串并分成列?

javascript - 如何遍历包含小于迭代器值的数组