更新:我刚刚击败了自己的32个if代码:
void test(char *file_char, unsigned int size)
{
char* file_ = file_char;
char* size_x = file_char+size;
char to_find = 0;
for(unsigned int i = 0; i < 10000; i++)
{
file_char = file_;
while(*file_char++ != to_find);//skip all characters till we find a 0
if(*file_char)//some if in order to avoid compiler removing our test code
cout << "found";
}
}
上面的代码要求0在数组中至少出现一次,否则将出现错误,但是比if代码和MUCH紧凑得多。
有什么方法可以使上面的代码更快? (具有一个char数组并尝试查找char出现的位置)?
我写了一些代码,我真的很困惑。
在里面:
int main()
{
FILE *file;
file = fopen("C:\\data.txt", "rb");
static const int size = 60000;
char *file_char = (char*)malloc(size);
unsigned int i = 0;
while(i < size)
fread(&file_char[i++], 1, 1, file);
clock_t clock_ = clock();
test(file_char, size);
std::cout << ((double)clock()-clock_)/1000;
return 0;
}
下面的代码需要3.5秒才能执行:
void test(char *file_char, unsigned int size)
{
for(unsigned int i = 0; i < 100000; i++)
{
unsigned int pos = 0;
char to_find = 0;
while(pos < size)
if(file_char[pos++] == to_find)
std::cout << "found";
}
}
但是下面的代码需要1.8秒,时间却减少了一半!
void test(char *file_char, unsigned int size)
{
for(unsigned int i = 0; i < 100000; i++)
{
unsigned int pos = 0;
char to_find = 0;
while(pos < size)
{
if(file_char[pos] == to_find)
std::cout << "found";
else if(file_char[pos+1] == to_find)
std::cout << "found";
else if(file_char[pos+2] == to_find)
std::cout << "found";
else if(file_char[pos+3] == to_find)
std::cout << "found";
else if(file_char[pos+4] == to_find)
std::cout << "found";
else if(file_char[pos+5] == to_find)
std::cout << "found";
else if(file_char[pos+6] == to_find)
std::cout << "found";
else if(file_char[pos+7] == to_find)
std::cout << "found";
else if(file_char[pos+8] == to_find)
std::cout << "found";
else if(file_char[pos+9] == to_find)
std::cout << "found";
else if(file_char[pos+10] == to_find)
std::cout << "found";
else if(file_char[pos+11] == to_find)
std::cout << "found";
else if(file_char[pos+12] == to_find)
std::cout << "found";
else if(file_char[pos+13] == to_find)
std::cout << "found";
else if(file_char[pos+14] == to_find)
std::cout << "found";
else if(file_char[pos+15] == to_find)
std::cout << "found";
else if(file_char[pos+16] == to_find)
std::cout << "found";
else if(file_char[pos+17] == to_find)
std::cout << "found";
else if(file_char[pos+18] == to_find)
std::cout << "found";
else if(file_char[pos+19] == to_find)
std::cout << "found";
else if(file_char[pos+20] == to_find)
std::cout << "found";
else if(file_char[pos+21] == to_find)
std::cout << "found";
else if(file_char[pos+22] == to_find)
std::cout << "found";
else if(file_char[pos+23] == to_find)
std::cout << "found";
else if(file_char[pos+24] == to_find)
std::cout << "found";
else if(file_char[pos+25] == to_find)
std::cout << "found";
else if(file_char[pos+26] == to_find)
std::cout << "found";
else if(file_char[pos+27] == to_find)
std::cout << "found";
else if(file_char[pos+28] == to_find)
std::cout << "found";
else if(file_char[pos+29] == to_find)
std::cout << "found";
else if(file_char[pos+30] == to_find)
std::cout << "found";
else if(file_char[pos+31] == to_find)
std::cout << "found";
pos+=32;
}
}
}
我使用的是Visual Studio 2012 x64,该程序从不提示任何内容,因为没有char为0。如何解释?如何在不使用32 if的情况下归档相同的性能?
编辑1:如果我创建64个ifs,则速度不会超过32个ifs版本。
编辑2:如果我删除了
else
并离开了ifs程序需要4秒钟。现在,如何解释以上不合理的结果呢?
最佳答案
为了确定,我已经进行了一些测试。
使用g++(在Linux和Windows下),我得到与Visual Studio相同的结果:
版本1(无显式循环展开)g++ -O3
7.5秒
版本2(显式循环展开)g++ -O3
2.1s
但是启用了 -funroll-loops 选项(通常默认情况下未启用此优化,因为它可能会或可能不会使其运行得更快):
版本1(无显式循环展开)g++ -O3 -funroll-loops
2.2秒
版本2(显式循环展开)g++ -O3 -funroll-loops
2.2秒
因此,这与循环展开有关。
编辑
您可以更改最后一个示例以显式插入哨兵,例如:
int main()
{
static const int size = 60000;
char *file_char = (char*)malloc(size+1); // The last element is the sentry
// ...Fill file_char[]...
file_char[size] = 0; // the sentry
// ...
}
因此
test
函数不会失败(当然,您必须检查是否找到了哨兵或“好”零,但如果是,则只是一个)。版本3(哨兵)
g++ -O3
0.68秒g++ -O3 -funroll-loops
0.72秒关于c++ - 低级的C/C++性能?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22072858/