如何解决使用callgrind或程序集修改来优化嵌套if和switch语句
考虑这段代码
| 34 static bool
| 35 _valid_character(char *str,size_t *idx)
| 36 {
| 37 char c = str[*idx];
| 38
| 39 if (c != '\\' && c != '"') {
| 40 (*idx) += 1;
| 41 return true;
| 42 } else if (c == '"') {
| 43 return false;
| 44 } else {
| 45 char b = str[(*idx) + 1];
| 46 switch (b) {
| 47 case '"':
| 48 case '\\':
| 49 case '/':
| 50 case 'b':
| 51 case 'f':
| 52 case 'n':
| 53 case 'r':
| 54 case 't':
| 55 (*idx) += 2;
| 56 return true;
| 57 default:
| 58 pprint_error("%s@%s:%d invalid escape sequnce \\%c%c (aborting)",| 59 __FILE_NAME__,__func__,__LINE__,c,b);
| 60 abort();
| 61 }
| 62 }
| 63 }
此功能是我的代码中完全变慢的根本原因。我尝试仅使用if语句,仅使用switch语句,但这是我可以想到的最佳优化,其中callgrind可以产生最佳性能。此功能约占运行时间的25%,所以按照可疑的(抱歉)80/20规则,对我而言,最大的兴趣是使此代码更快。
下面是在此函数中用kcachegrind可视化的callgrind输出。
callgrind似乎在说我的第一个跳转是最糟糕的跳转,但是我已经尝试了所有if语句的组合以尽量减少跳转,并且每次第一次跳转时 是最糟糕的跳跃。
此代码是使用clang编译的
clang ... -Weverything -Werror -Wpedantic -m64 -O0 -g
所以我的问题是优化此代码和替代技术(包括程序集修改)以优化此简单但致命的代码的最佳方法是什么。
我想继续使用-O0
,因为我发现它对于调试和查找优化最有用。 -O1,2,3,fast
倾向于抽象很多,以更好地了解正在发生的事情。
-编辑1 有人要求提供示例输入。
char cstr[BUF] = "abcdefghijklmnopqrstuvwxyz\"randomgarbageafterthis";
size_t idx = 0;
while (_valid_character(cstr,&idx));
最后,输入只是一个字符串,并且将调用循环,直到结尾"
字符为止。结束的idx值将cstr[idx] == '"''
设置为true。
解决方法
如果您确实要优化代码,请使用笔和纸并创建一个布尔逻辑表,并凭自己的意愿优化其代数。之后,重新创建代码,请在您的break;
语句中使用switch
。
例如:
这是您的代码。
if (c != '\\' && c != '"')
{
(*idx) += 1;
return true;
}
这比上一个要快。
if (c != '\\')
{
if (c != '"')
{
(*idx) += 1;
return true;
}
}
请不要使用已注册的常量来比较if (c != '\\')
之类的一些字符。
register const char BACKSLASH = '\\';
也可以:
register char c = str[*idx];
CPU寄存器中加载的常量和变量的比较速度更快。
if (c != BACKSLASH)
通常,如果要使用快速代码,请仅使用if
和else
并使用简单的布尔比较参数。
编辑:
代码示例1:
if (c != '\\')
{
if (c == '"')
{
return false;
}
else
{
(*idx) += 1;
return true;
}
}
等效于:
代码示例2:
if (c != '\\')
{
if (c != '"')
{
(*idx) += 1;
return true;
}
}
else if (c == '"')
{
return false;
}
但是第一个代码示例仅比较2次,但是第二个代码示例比较3次。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。