2

我已经在 410k 行的大型数据集上实现了朴素贝叶斯算法。现在我的所有记录都得到了正确分类,但问题是程序花了将近一个小时将记录写入相应的文件。改进的最佳方法是什么我的代码的性能。这是下面的代码。这段代码正在将 410k 记录写入相应的文件。谢谢。

    fp=fopen("sales_ok_fraud.txt","r");
        while(fgets(line,80,fp)!=NULL) //Reading each line from file to calculate the file size.
        {
                token = strtok(line,",");
                token = strtok(NULL,",");
                token = strtok(NULL,",");
                token = strtok(NULL,",");
                token = strtok(NULL,",");
                token = strtok(NULL,",");
                token1 = strtok(token,"\n");
                memcpy(mystr,&token1[0],strlen(token1)-1);
                mystr[strlen(token1)-1] = '\0';

        if( strcmp(mystr,"ok") == 0 )
            counter_ok++;
        else 
        counter_fraud++;       
    }
    printf("The no. of records with OK label are %f\n",counter_ok);
    printf("The no. of records with FRAUD label are %f\n",counter_fraud);

    prblty_ok = counter_ok/(counter_ok+counter_fraud);
    prblty_fraud = counter_fraud/(counter_ok+counter_fraud);
    printf("The probability of OK records is %f\n",prblty_ok);
    printf("The probability of FRAUD records is %f\n",prblty_fraud);
    fclose(fp);

    fp=fopen("sales_unknwn.txt","r");
    fp2=fopen("sales_unknown_ok_classified.txt","a");
    fp3=fopen("sales_unknown_fraud_classified.txt","a");
    while(fgets(line1,80,fp)!=NULL) //Reading each line from file to calculate the file size.
        {
                unknwn_attr1 = strtok(line1,",");
                unknwn_attr2 = strtok(NULL,",");
                unknwn_attr3 = strtok(NULL,",");
                unknwn_attr4 = strtok(NULL,",");
                unknwn_attr5 = strtok(NULL,",");

        //printf("%s-%s-%s-%s-%s\n",unknwn_attr1,unknwn_attr2,unknwn_attr3,unknwn_attr4,unknwn_attr5);

        fp1=fopen("sales_ok_fraud.txt","r");
        while(fgets(line,80,fp1)!=NULL) //Reading each line from file to calculate the file size.
            {
            ok_fraud_attr1 = strtok(line,",");
                    ok_fraud_attr2 = strtok(NULL,",");
                    ok_fraud_attr3 = strtok(NULL,",");
                    ok_fraud_attr4 = strtok(NULL,",");
                    ok_fraud_attr5 = strtok(NULL,",");
            ok_fraud_attr6 = strtok(NULL,",");
                    memcpy(ok_fraud_attr6_str,&ok_fraud_attr6[0],strlen(ok_fraud_attr6)-2);
                    ok_fraud_attr6_str[strlen(ok_fraud_attr6)-2] = '\0';
            //ok_fraud_attr6[strlen(ok_fraud_attr6)-2] = '\0';      
            //printf("Testing ok_fraud_attr6 - %s-%d\n",ok_fraud_attr6_str,strlen(ok_fraud_attr6_str)); 
            if( strcmp(ok_fraud_attr6_str,"ok") == 0 )
            {
                if( strcmp(unknwn_attr2,ok_fraud_attr2) == 0 )
                counter_ok_attr2++;

                if( strcmp(unknwn_attr3,ok_fraud_attr3) == 0 )
                counter_ok_attr3++;

                if( strcmp(unknwn_attr4,ok_fraud_attr4) == 0 )
                counter_ok_attr4++;

                if( strcmp(unknwn_attr5,ok_fraud_attr5) == 0 )
                counter_ok_attr5++;
            }

                    if( strcmp(ok_fraud_attr6_str,"fraud") == 0 )
                        {
                if( strcmp(unknwn_attr2,ok_fraud_attr2) == 0 )
                counter_fraud_attr2++;

                if( strcmp(unknwn_attr3,ok_fraud_attr3) == 0 )
                counter_fraud_attr3++;

                if( strcmp(unknwn_attr4,ok_fraud_attr4) == 0 )
                counter_fraud_attr4++;

                if( strcmp(unknwn_attr5,ok_fraud_attr5) == 0 )
                counter_fraud_attr5++;
            }
        }
        fclose(fp1);
        if(counter_ok_attr2 == 0)
        prblty_attr2_given_ok = (counter_ok_attr2+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
        else
        prblty_attr2_given_ok = (counter_ok_attr2)/(counter_ok);

        if(counter_ok_attr3 == 0)
        prblty_attr3_given_ok = (counter_ok_attr3+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
        else
                prblty_attr3_given_ok = (counter_ok_attr3)/(counter_ok);

        if(counter_ok_attr4 == 0)
        prblty_attr4_given_ok = (counter_ok_attr4+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
        else
                prblty_attr4_given_ok = (counter_ok_attr4)/(counter_ok);

        if(counter_ok_attr5 == 0)
        prblty_attr5_given_ok = (counter_ok_attr5+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
        else
                prblty_attr5_given_ok = (counter_ok_attr5)/(counter_ok);

        if(counter_fraud_attr2 == 0)
        prblty_attr2_given_fraud = (counter_fraud_attr2+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
        else
                prblty_attr2_given_fraud = (counter_fraud_attr2)/(counter_fraud);

        if(counter_fraud_attr3 == 0)
        prblty_attr3_given_fraud = (counter_fraud_attr3+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
        else
                prblty_attr3_given_fraud = (counter_fraud_attr3)/(counter_fraud);

        if(counter_fraud_attr4 == 0)
        prblty_attr4_given_fraud = (counter_fraud_attr4+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
        else
                prblty_attr4_given_fraud = (counter_fraud_attr4)/(counter_fraud);

        if(counter_fraud_attr5 == 0)
        prblty_attr5_given_fraud = (counter_fraud_attr5+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
        else
                prblty_attr5_given_fraud = (counter_fraud_attr5)/(counter_fraud);

        total_prblty_ok = prblty_ok*prblty_attr2_given_ok*prblty_attr3_given_ok*prblty_attr4_given_ok*prblty_attr5_given_ok;
        total_prblty_fraud = prblty_fraud*prblty_attr2_given_fraud*prblty_attr3_given_fraud*prblty_attr4_given_fraud*prblty_attr5_given_fraud;


//      printf("Testing counts for OK - %f - %f - %f - %f\n",counter_ok_attr2,counter_ok_attr3,counter_ok_attr4,counter_ok_attr5);
//      printf("Testing counts for FRAUD - %f - %f - %f - %f\n",counter_fraud_attr2,counter_fraud_attr3,counter_fraud_attr4,counter_fraud_attr5);
//      printf("Testing attribute probabilities for OK - %f - %f - %f - %f\n",prblty_attr2_given_ok,prblty_attr3_given_ok,prblty_attr4_given_ok,prblty_attr5_given_ok);
//      printf("Testing attribute probabilities for FRAUD- %f - %f - %f - %f\n",prblty_attr2_given_fraud,prblty_attr3_given_fraud,prblty_attr4_given_fraud,prblty_attr5_given_fraud);
//      printf("The final probabilities are %f - %f\n",total_prblty_ok,total_prblty_fraud);

        if(total_prblty_ok > total_prblty_fraud)
        {
            fprintf(fp2,"%s,%s,%s,%s,%s,ok\n",unknwn_attr1,unknwn_attr2,unknwn_attr3,unknwn_attr4,unknwn_attr5);
        }   
        else
        {
            fprintf(fp3,"%s,%s,%s,%s,%s,fraud\n",unknwn_attr1,unknwn_attr2,unknwn_attr3,unknwn_attr4,unknwn_attr5);
        }
        counter_ok_attr2=counter_ok_attr3=counter_ok_attr4=counter_ok_attr5=0;
        counter_fraud_attr2=counter_fraud_attr3=counter_fraud_attr4=counter_fraud_attr5=0;
    }

    fclose(fp);
        fclose(fp2);    
        fclose(fp3);    
4

3 回答 3

5

我可以立即看到您可以做的几件事,按照我尝试的顺序:

  1. 停止在输出文件上重复打开-写入-关闭、打开-写入-关闭意识形态。他们的名字是固定的和有限的。在这件事开始时适当地打开它们,然后在完成后冲洗并关闭。
  2. 有几个逻辑结构可以显着简化。
  3. 你的strlen()横冲直撞需要显着减少。大多数体面的优化编译器会检测到未更改的源并优化对已知未更改的 char-ptr 的后续调用,所以我会最后执行此操作(但老实说,我仍然会这样做,因为strlen()在相同的数据。
  4. 与 OP对话后添加:您一遍又一遍地重新解析相同的数据文件 (sales_ok_fraud.txt),一次是针对 sales_unknwn.txt 中的数据行。如果 sales_ok_fraud.txt 可以放入内存,那么 12gB/abg-line-length 是很多不必要的重复解析。加载该数据一次,计算其基本统计信息一次,并将其中的数据和统计信息用于其余的数据处理。

逻辑简化

您可以特别在一个地方减少大量工作,改变这一点:

    if(strcmp(unknwn_attr2,ok_fraud_attr2) == 0 && strcmp(ok_fraud_attr6_str,"ok") == 0)
        counter_ok_attr2++;

    if(strcmp(unknwn_attr3,ok_fraud_attr3) == 0 && strcmp(ok_fraud_attr6_str,"ok") == 0)
        counter_ok_attr3++;

    if(strcmp(unknwn_attr4,ok_fraud_attr4) == 0 && strcmp(ok_fraud_attr6_str,"ok") == 0)
        counter_ok_attr4++;

    if(strcmp(unknwn_attr5,ok_fraud_attr5) == 0 && strcmp(ok_fraud_attr6_str,"ok") == 0)
        counter_ok_attr5++;

    if(strcmp(unknwn_attr2,ok_fraud_attr2) == 0 && strcmp(ok_fraud_attr6_str,"fraud") == 0)
        counter_fraud_attr2++;

    if(strcmp(unknwn_attr3,ok_fraud_attr3) == 0 && strcmp(ok_fraud_attr6_str,"fraud") == 0)
        counter_fraud_attr3++;

    if(strcmp(unknwn_attr4,ok_fraud_attr4) == 0 && strcmp(ok_fraud_attr6_str,"fraud") == 0)
        counter_fraud_attr4++;

    if(strcmp(unknwn_attr5,ok_fraud_attr5) == 0 && strcmp(ok_fraud_attr6_str,"fraud") == 0)
        counter_fraud_attr5++;

对此:

    if (strcmp(ok_fraud_attr6_str, "ok") == 0)
    {
        if(strcmp(unknwn_attr2,ok_fraud_attr2) == 0)
            counter_ok_attr2++;

        if(strcmp(unknwn_attr3,ok_fraud_attr3) == 0 )
            counter_ok_attr3++;

        if(strcmp(unknwn_attr4,ok_fraud_attr4) == 0)
            counter_ok_attr4++;

        if(strcmp(unknwn_attr5,ok_fraud_attr5) == 0)
            counter_ok_attr5++;
    }
    else if (strcmp(ok_fraud_attr6_str,"fraud") == 0)
    {
        if(strcmp(unknwn_attr2,ok_fraud_attr2) == 0)
            counter_fraud_attr2++;

        if(strcmp(unknwn_attr3,ok_fraud_attr3) == 0)
            counter_fraud_attr3++;

        if(strcmp(unknwn_attr4,ok_fraud_attr4) == 0)
            counter_fraud_attr4++;

        if(strcmp(unknwn_attr5,ok_fraud_attr5) == 0)
            counter_fraud_attr5++;
    }

前装式sales_ok_fraud.txt

以下内容依赖于您的sales_ok_fraud.txtstats 文件的数据格式的神圣性,同时在验证所述格式时尽可能地迂腐。它分配了一块足够大的内存来保存整个文件加一个字符,以将整个正文视为单个空项字符串。然后通过您之前使用的相同通用算法对该缓冲区进行拼凑。结果将是一个指向固定长度字符指针数组的指针表,然后可以在您当前(并重复)打开、解析、使用和丢弃所有内容的同一位置迭代地使用这些指针。

// declare an array of six string pointers
typedef char *OFAttribs[6];

// loads a table consisting of the following format:
//
// str1,str2,str3,str4,str5,str6\n
// str1,str2,str3,str4,str5,str6\n
// ...
// str1,str2,str3,str4,str5,str6
//
// any deviation from the above will cause premature termination of the loop
//  but will return whatever was able to be parsed up to the point of failure.
//  the caller should therefore always `free()` the resulting table and data
//  pointers.

size_t init_ok_fraud_data(const char *fname, OFAttribs **ppTable, char **ppTableData)
{
    if (!fname || !*fname)
        return 0;

    // check file open for thumbs up
    FILE *fp = fopen(fname, "rb");
    if (!fp)
        return 0;

    // allocate enough memory to hold the entire file, plus a terminator
    fseek(fp, 0,  SEEK_END);
    long len = ftell(fp);
    fseek(fp, 0,  SEEK_SET);

    // allocate enough ram for the entire file plus terminator
    OFAttribs *pTable = NULL;
    size_t nTableLen = 0;
    char *pTableData =  malloc((len+1) * sizeof(char));
    if (NULL != pTableData)
    {
        fread(pTableData , len, 1, fp);
        pTableData[len] = 0;
    }

    // no longer need the file
    fclose(fp);

    // prime first token
    char *token = strtok(pTableData, ",");
    while (token)
    {
        // read next line of tokens
        OFAttribs attribs = { NULL };
        for (int i=0;i<4 && token; ++i)
        {
            attribs[i] = token;
            token = strtok(NULL, ",");
        }

        // filled 0..3, set lat token and move on
        if (attribs[3] && token)
        {
            // next-to-last entry set
            attribs[4] = token;

            // line enter is only terminated by newline
            token = strtok(NULL, "\n");
            if (token)
            {
                // proper format. 6 parms, 5 commas, one new-line.
                attribs[5] = token;
                size_t slen = strlen(token);
                if (slen > 0)
                {
                    while (isspace(token[--slen]))
                        token[slen] = 0;
                }

                // make space on the master list for another.
                OFAttribs *tmp = realloc(pTable, sizeof(*tmp) * (nTableLen+1));
                if (NULL != tmp)
                {
                    pTable = tmp;
                    memcpy(pTable + nTableLen++, attribs, sizeof(attribs));
                }
                else
                {   // allocation failure.
                    printf("Error allocating memory for expanding OKFraud data set");
                    exit(EXIT_FAILURE);
                }
            }
            else
            {   // not good.
                printf("Invalid line format detected. Expected ok/fraud\\n");
                break;
            }

            // next token of new line
            token = strtok(NULL, ",");
        }
    }

    // set output variables
    *ppTable = pTable;
    *ppTableData = pTableData;
    return nTableLen;
}

把它放在一起

合并上述所有内容会对您的代码库产生以下影响:

// load the ok_fraud table ONCE.
OFAttribs *okfr = NULL;
char *okfr_data = NULL;
size_t okfr_len = init_ok_fraud_data("sales_ok_fraud.txt", &okfr, &okfr_data);

// walk table to determine probabilities of ok and fraud states.
//  note: this really should be done as part of the loader.
for (size_t i=0;i<okfr_len; ++i)
{
    if (0 == strcmp("ok", okfr[i][5]))
        ++counter_ok;
    else
        ++counter_fraud;
}

printf("The no. of records with OK label are %f\n",counter_ok);
printf("The no. of records with FRAUD label are %f\n",counter_fraud);

// compute probabilites for ok and fraud states
prblty_ok = (float)counter_ok/(float)(okfr_len);
prblty_fraud = (float)counter_fraud/(float)(okfr_len);
printf("The probability of OK records is %f\n",prblty_ok);
printf("The probability of FRAUD records is %f\n",prblty_fraud);

fp=fopen("sales_unknwn.txt","r");
fp2=fopen("sales_unknown_ok_classified.txt","w");
fp3=fopen("sales_unknown_fraud_classified.txt","w");
while(fgets(line1,sizeof(line1),fp)!=NULL) //Reading each line from file to calculate the file size.
{
    char *unknwn_attr1 = strtok(line1,",");
    char *unknwn_attr2 = strtok(NULL,",");
    char *unknwn_attr3 = strtok(NULL,",");
    char *unknwn_attr4 = strtok(NULL,",");
    char *unknwn_attr5 = strtok(NULL,",");

    //printf("%s-%s-%s-%s-%s\n",unknwn_attr1,unknwn_attr2,unknwn_attr3,unknwn_attr4,unknwn_attr5);

    for (size_t i=0;i<okfr_len; ++i)
    {

        if( strcmp(okfr[i][5], "ok") == 0 )
        {
            // ok case
            if( strcmp(unknwn_attr2, okfr[i][1]) == 0 )
                counter_ok_attr2++;

            if( strcmp(unknwn_attr3, okfr[i][2]) == 0 )
                counter_ok_attr3++;

            if( strcmp(unknwn_attr4, okfr[i][3]) == 0 )
                counter_ok_attr4++;

            if( strcmp(unknwn_attr5, okfr[i][4]) == 0 )
                counter_ok_attr5++;
        }

        else // fraud case
        {
            if( strcmp(unknwn_attr2, okfr[i][1]) == 0 )
                counter_fraud_attr2++;

            if( strcmp(unknwn_attr3, okfr[i][2]) == 0 )
                counter_fraud_attr3++;

            if( strcmp(unknwn_attr4, okfr[i][3]) == 0 )
                counter_fraud_attr4++;

            if( strcmp(unknwn_attr5, okfr[i][4]) == 0 )
                counter_fraud_attr5++;
        }
    }

    if(counter_ok_attr2 == 0)
        prblty_attr2_given_ok = (counter_ok_attr2+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
    else
        prblty_attr2_given_ok = (counter_ok_attr2)/(counter_ok);

    if(counter_ok_attr3 == 0)
        prblty_attr3_given_ok = (counter_ok_attr3+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
    else
        prblty_attr3_given_ok = (counter_ok_attr3)/(counter_ok);

    if(counter_ok_attr4 == 0)
        prblty_attr4_given_ok = (counter_ok_attr4+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
    else
        prblty_attr4_given_ok = (counter_ok_attr4)/(counter_ok);

    if (counter_ok_attr5 == 0)
        prblty_attr5_given_ok = (counter_ok_attr5+arbitrary_value*prblty_ok)/(counter_ok+arbitrary_value);
    else
        prblty_attr5_given_ok = (counter_ok_attr5)/(counter_ok);

    if(counter_fraud_attr2 == 0)
        prblty_attr2_given_fraud = (counter_fraud_attr2+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
    else
        prblty_attr2_given_fraud = (counter_fraud_attr2)/(counter_fraud);

    if(counter_fraud_attr3 == 0)
        prblty_attr3_given_fraud = (counter_fraud_attr3+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
    else
        prblty_attr3_given_fraud = (counter_fraud_attr3)/(counter_fraud);

    if(counter_fraud_attr4 == 0)
        prblty_attr4_given_fraud = (counter_fraud_attr4+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
    else
        prblty_attr4_given_fraud = (counter_fraud_attr4)/(counter_fraud);

    if(counter_fraud_attr5 == 0)
        prblty_attr5_given_fraud = (counter_fraud_attr5+arbitrary_value*prblty_fraud)/(counter_fraud+arbitrary_value);
    else
        prblty_attr5_given_fraud = (counter_fraud_attr5)/(counter_fraud);

    total_prblty_ok = prblty_ok*prblty_attr2_given_ok*prblty_attr3_given_ok*prblty_attr4_given_ok*prblty_attr5_given_ok;
    total_prblty_fraud = prblty_fraud*prblty_attr2_given_fraud*prblty_attr3_given_fraud*prblty_attr4_given_fraud*prblty_attr5_given_fraud;


    //      printf("Testing counts for OK - %f - %f - %f - %f\n",counter_ok_attr2,counter_ok_attr3,counter_ok_attr4,counter_ok_attr5);
    //      printf("Testing counts for FRAUD - %f - %f - %f - %f\n",counter_fraud_attr2,counter_fraud_attr3,counter_fraud_attr4,counter_fraud_attr5);
    //      printf("Testing attribute probabilities for OK - %f - %f - %f - %f\n",prblty_attr2_given_ok,prblty_attr3_given_ok,prblty_attr4_given_ok,prblty_attr5_given_ok);
    //      printf("Testing attribute probabilities for FRAUD- %f - %f - %f - %f\n",prblty_attr2_given_fraud,prblty_attr3_given_fraud,prblty_attr4_given_fraud,prblty_attr5_given_fraud);
    //      printf("The final probabilities are %f - %f\n",total_prblty_ok,total_prblty_fraud);

    if(total_prblty_ok > total_prblty_fraud)
    {
        fprintf(fp2,"%s,%s,%s,%s,%s,ok\n",unknwn_attr1,unknwn_attr2,unknwn_attr3,unknwn_attr4,unknwn_attr5);
    }
    else
    {
        fprintf(fp3,"%s,%s,%s,%s,%s,fraud\n",unknwn_attr1,unknwn_attr2,unknwn_attr3,unknwn_attr4,unknwn_attr5);
    }
    counter_ok_attr2=counter_ok_attr3=counter_ok_attr4=counter_ok_attr5=0;
    counter_fraud_attr2=counter_fraud_attr3=counter_fraud_attr4=counter_fraud_attr5=0;
}

// free the table data and dynamic pointer array
free(okfr);
free(okfr_data);

fclose(fp);
fclose(fp2);
fclose(fp3);
return 0;

这些只是一些想法。可以肯定的是,其中还有更多的东西,但是这些应该极大地有助于处理具有连续输出的文件单前向扫描,这与在这些情况下将获得的效率差不多。毫无疑问,这三者的组合:单个文件打开+关闭、逻辑缩减和对 sales_ok_fraud.txt 文件进行单解析缓存将有巨大的性能提升,尤其是其中的第一个和最后一个。

编辑协助 OP 更新此处理器以预先加载 sales_ok_fraud.txt 文件内容,从而消除重复加载、解析并迅速丢弃大约 15000 多行要重复解析的文本(每个主源输入行一次)。上面的答案相应更新。

于 2012-11-18T01:32:21.840 回答
1

@m02ph3u5 是对的。保持文件打开,将 fopen 和 fclose 的调用排除在循环之外。

inputFile = fopen("sales_unknwn.txt","r");
okayFile = fopen("sales_ok_fraud.txt","r");
unknownOkayFile = fopen("sales_unknown_ok_classified.txt","a");
unknownFraudFile = fopen("sales_unknown_fraud_classified.txt","a");

// your loops go here

fclose(inputFile);
fclose(okayFile);
fclose(unknownOkayFile);
fclose(unknownFraudFile);

如果它仍然很慢,请在您的应用程序上运行采样分析器,并将测试数据的子集作为输入,以保持快速周转。这将告诉您程序将时间花在哪里。你可能会感到惊讶。如果您不知道要使用探查器,则可以通过使用调试器运行您的应用程序来对采样探查器进行穷人模拟,反复闯入调试器并注意它正在运行的函数。如果您在某个功能或大多数时间在某条线上,这可能是您可以优化的热点。

于 2012-11-18T01:09:10.617 回答
0

几点建议:

• 重复打开文件以进行追加、关闭和重新打开它们非常昂贵。这是因为 I/O 比内存访问慢得多,并且每次写入时都强制磁盘打开每个文件并寻找到末尾。 最好在开始时打开它们一次并在结束时关闭它们,除非您担心程序会崩溃并且您会丢失迄今为止编写的数据。

• 您可以替换行

memcpy(ok_fraud_attr6_str, &ok_fraud_attr6[0], strlen(ok_fraud_attr6)-2);
ok_fraud_attr6_str[strlen(ok_fraud_attr6)-2] = '\0';

ok_fraud_attr6[strlen(ok_fraud_attr6)-2] = '\0';

然后ok_fraud_attr6在您的测试中使用。由于strtok具有破坏性(快速搜索将值得您花时间了解为什么使用它通常是一个坏主意),您不必担心保留lineor的内容ok_fraud_attr6

• 当您发现自己一遍又一遍地编写相同的代码时,通常表明您的算法效率低下。代替

if ((some_unique_test) && (a_common_test))
  do_some_stuff;
if ((some_other_unique_test) && (a_common_test))
  do_other_stuff;

你可以写

if (a_common_test) {
  if (some_unique_test)
    do_some_stuff;
  if (some_other_unique_test)
    do_other_stuff;
}

但是请注意,只有第一个建议可能会对程序的执行时间产生显着影响,尽管它们都是需要学习的好习惯。

Jason 对使用分析器的建议是非常好的建议,怎么强调都不为过。程序员——即使是经验丰富的程序员——在预测他们的代码中的瓶颈在哪里方面是出了名的糟糕。除了调试器,配置文件是您最好的朋友。

于 2012-11-18T01:24:55.473 回答