我进行了以下测试。
charspeed.c
#include <stdio.h>
#include <time.h>
#define CHAR_COUNT 26
#define CHAR_LIST "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
static const char *CHAR_ARRAY = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#define RUN_COUNT 1000000000
#define GET_CLOCK (float)clock() / CLOCKS_PER_SEC
int main()
{
long long int sum = 0;
float start, end;
start = GET_CLOCK;
for (size_t i = 0; i < RUN_COUNT; i++)
{
char test = CHAR_LIST[i % CHAR_COUNT];
sum += test; // Force the loop to run!
}
end = GET_CLOCK;
printf("#define Time: %f\n", end - start);
start = GET_CLOCK;
for (size_t i = 0; i < RUN_COUNT; i++)
{
char test = CHAR_ARRAY[i % CHAR_COUNT];
sum += test; // Must be the same as fist loop!
}
end = GET_CLOCK;
printf("static const *CHAR_ARRAY Time: %f\n", end - start);
printf("sum = %lld\n", sum); // Must access "sum" after loops!
return 0;
}
它的输出
#define 时间:1.741000
static const *CHAR_ARRAY 时间:1.868000
为什么使用 #define 指令的字符串文字比预初始化的静态字符数组更快?字符串文字到底存储在哪里以及为什么在 block 范围内访问它们更快?
使用的编译器选项是gcc -o charspeed charspeed.c
最佳答案
只是一个补充答案来完成其他答案。
字符串文字不是 const char *
。
原因是 const char *
可以重新分配。在你的情况下,这意味着你可以这样做 CHAR_ARRAY = "foo";
.
实际上,这意味着编译器无法优化处理 const char *
的代码。比处理字符串文字的代码。
要解决此问题,您可以使用以下方法之一:
const char *const CHAR_ARRAY = "...";
const char CHAR_ARRAY[] = "...";
这应该保证与字符串文字相同的性能。
但是,在您的情况下,由于您声明 CHAR_ARRAY
如static
,这意味着编译器可以只查看当前源文件,如果 CHAR_ARRAY
可以重新分配给。
实际上,这意味着,假设启用优化:
- 对于字符串文字,
const char *const
或const char[]
,将生成相同的汇编代码(A)。 - 对于非静态
const char *
将生成不同的汇编代码 (B),可能会更慢,因为它们是附加的间接寻址,并且在编译时无法知道结果。 - 对于
static const char *
,它将使用汇编代码 (A) 或 (B),具体取决于编译器是否可以证明指针可能被重新分配。例如,如果您添加一个函数void f() { CHAR_ARRAY = "foo"; }
在代码中的任何地方,如果禁止编译器使用程序集 (A),则将使用 (B)。
关于c - 为什么字符串文字比静态字符数组更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58051488/