分支或ftell()正在减速
Branching or ftell() that is Slowing?
我在windows操作系统上查看agent .h文件,我想看到没有注释的c++代码。为了更清楚地看到我的旧程序的代码,我把它们分开了,但令我惊讶的是,它只花了2秒钟就完成了。文件的大小是605KB,所以它不是那么糟糕。为什么这么慢。我怀疑是函数ftell()在做这件事,但我真的说不出来。是分支减慢了速度还是ftell()?如果是ftell(),那么将FILE指针抛出的更好方法是什么?
编辑
#include <stdio.h>
#include <time.h>
#define NOT_COMMENT (!DOUBLESLASH_Comment && !ASTERISK_SLASH_Comment)
int main(int argc,char *argv[])
{
clock_t t1 = clock();
FILE *input , *output;
if( fopen_s(&input,argv[1],"r") )
{
printf("error opening file %sn",argv[1]);
return 0;
}
if( fopen_s(&output,argv[2],"w") )
{
printf("error opening file %sn",argv[2]);
return 0;
}
char c , d;
//escape flag
bool DOUBLESLASH_Comment = 0 , ASTERISK_SLASH_Comment = 0 , flag = 0;
/* single quotes / double quotes */
int s_QUOTED = 0 , d_QUOTED = 0;
while( (c=getc(input)) != EOF )
{
switch(c)
{
case '':
{
if( NOT_COMMENT )
{
if( flag == 1 )
flag = 0;
else
flag = 1;
}
}break;
case ''':
{
if( NOT_COMMENT && !d_QUOTED )
{
if( !flag )
{
s_QUOTED++;
}
}
}break;
case '"':
{
if( NOT_COMMENT && !flag )
{
if( !s_QUOTED )
{
d_QUOTED++;
}
}
}break;
case '/':
{
if( NOT_COMMENT && !d_QUOTED )
{
if( (d=getc(input)) == '*' )
{
ASTERISK_SLASH_Comment = 1;
}
else if( d == '/' )
{
DOUBLESLASH_Comment = 1;
}
else
{
if( d != EOF )
{
ungetc(d,input);
}
}
}
}break;
case '*':
{
if( ASTERISK_SLASH_Comment )
{
if( (d=getc(input)) == '/')
{
if( (c=getc(input)) == EOF )
return 0;
ASTERISK_SLASH_Comment = 0;
}
else
{
if( d != EOF )
{
ungetc(d,input);
}
}
}
}break;
case 'n':
{
if( DOUBLESLASH_Comment )
{
DOUBLESLASH_Comment = 0;
}
}break;
}
if( NOT_COMMENT && c != '' ) flag = 0;
if( d_QUOTED == 2 ) d_QUOTED = 0;
if( s_QUOTED == 2 ) s_QUOTED = 0;
if( NOT_COMMENT )
{
fprintf(output,"%c",c);
}
}
fclose(input);
fclose(output);
clock_t t2 = clock();
double elapsed = (double)(t2 - t1) / CLOCKS_PER_SEC;
printf("time elapsed : %fn",elapsed);
}
如果没有在分析器中实际测量代码的速度(并且使用作为输入的文件,因为我使用的文件可能有不同的注释集,等等,从而触发不同的行为),则很难确定。但是看起来您使用fseek( ... )
只是为了向后移动一个字符。在这种情况下,为一个字符的前瞻性编写自己的函数将是一个更好的选择。
像这样:
char lookahead = ' ';
bool havelookahead = false;
char getNextChar(FILE *input)
{
if (havelookahead)
{
havelookahead = false;
return lookahead;
}
return getc(input);
}
char peekChar(FILE *input)
{
if (!havelookahead)
{
lookahead = getc(input);
havelookahead = true;
}
return lookahead;
}
然后将循环开头的getc
替换为getNextChar
,然后用peekChar
检查下一个字符(后面跟着一个虚拟的getNextChar()
以消耗它)。
对于解析来说,这通常是一个有用的模式——无论是在字符级别还是在令牌级别,因此了解它是如何工作的是很有好处的。
你也可以使用标准的ungetc
来"放回"你看过的角色。
这是否会使你的代码运行得更快还很难说,就像我在开头说的。
我无法编译您的代码,因此我无法进行测试。但我怀疑瓶颈是fseek
而不是ftell
。拒绝字符是解析文件中的常见任务…并且应该由库或带有缓冲的中间层来实现。在这种情况下(拒绝单个字符),您可以使用ungetc
来实现。
所以你应该替换
fseek( file , ( ftell(file) - 1 ) , SEEK_SET );
ungetc('*', file); // ungetc('/', file); the second time.
相关文章:
- IPC使用多个管道和分支进程来运行Python程序
- 如何删除peer if else分支中的冗长句子
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 如何正确地将分支添加到已存在的树中
- 如何将分支添加到已存在的TTree:ROOT
- 如何删除 LLVM 中的不规则分支?
- 如果以下行不包含决策或分支,GDB 无法单步跳过函数
- 函数指针与条件分支
- 分支未在 Linux 上采用
- 如何删除分支因子不一致的树,最大为 30,40
- std::shared_ptr vs std::make_shared:意外的缓存未命中和分支预测
- 更改 git 分支名称后,在项目的 Visual Studio 代码中丢失智能感知(建议,转到定义C++
- 条件分支评估
- 是否可以使用函数指针数组来删除分支
- 基于派生类型的编译时行为分支
- L 系统树无法正确分支
- Antlr4 C++访问模棱两可的分支
- 如何为不同的分支使用不同的 Xcode 版本(或具有不同 Clang 版本的最新 Xcode)?
- 如何防止特定的QTreeView分支被拖动?
- 分支或ftell()正在减速