-1

レコード要素を含むxmlファイルがあります。レコード要素内のデータを PCAP 形式に変換しています。コードを以下に示します。do ループ内では、6 ミリ秒しか費やしていませんが、ループの境界で正確に時間をかけると、43 ミリ秒を費やしていることがわかります..この違いはどこから来ているのでしょうか? また、ループ内のメモリを新しくしています。それは許容できる慣行ですか、それともメモリをゼロにして再利用する必要がありますか? 再利用によってパフォーマンスが向上しますか? ループ内の時間は次のとおりです。

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466589、終了時刻: 1030466589

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466590、終了時刻: 1030466590

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466591、終了時刻: 1030466591

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466591、終了時刻: 1030466591

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466592、終了時刻: 1030466592

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466593、終了時刻: 1030466593

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466593、終了時刻: 1030466593

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466594、終了時刻: 1030466594

2012-05-14 07:26:48 スレッド ID (19404) トレース: 開始時刻: 1030466595、終了時刻: 1030466595

ただし、do ループの境界の時間は 2012-05-14 07:26:48 ThreadID(19404) TRACE:start Time:1030466584,End Time:1030466627 です。

        static struct tms st_cpu;
        static struct tms et_cpu;
        clock_t end_time;
        clock_t start_time;
        char szData[100] = {0};
        clock_t st_total_time;
        clock_t et_total_time;
        static struct tms st_total_cpu;
        static struct tms et_total_cpu;
        st_total_time = times(&st_total_cpu);
        do {
        char *pBuffer = new char[m_nBufferLen];
        memset(pBuffer,0,m_nBufferLen);
            if(fgets(pBuffer,m_nBufferLen,fpcap) != NULL)
            {
                    char *pRecord = NULL;
                    if((pRecord = strstr(pBuffer,"<rec ")) != NULL)
                    {
                            start_time = times(&st_cpu);
                            CXMLParser objXMLParser(pBuffer);
                            objXMLParser.ProcessRecord();
                            objPCAPGenerator.GeneratePCAPRecord(&objXMLParser);
                            end_time = times(&et_cpu);

                            sprintf(szData,"start Time:%ld,End Time:%ld",start_time,end_time);
                            CLog::PrintLog(DBG_TRACE,"%s",szData);


                            sprintf(szData,"Real Time: %ld,UserTime:%ld,SystemTime:%ld",
                                            end_time-start_time,
                                            (et_cpu.tms_utime + et_cpu.tms_cutime) - (st_cpu.tms_utime + st_cpu.tms_cutime),
                                            (et_cpu.tms_stime + et_cpu.tms_cstime) -(st_cpu.tms_stime + st_cpu.tms_cstime)
                                            );
                            CLog::PrintLog(DBG_TRACE,"%s",szData);
                    }
            }
            else
            {
                    bEnd = true;
            }
    }while(bEnd != true);

    et_total_time = times(&et_total_cpu);

    sprintf(szData,"start Time:%ld,End Time:%ld",st_total_time,et_total_time);
    CLog::PrintLog(DBG_TRACE,"%s",szData);


    sprintf(szData,"Total Real Time: %ld,Total UserTime:%ld,Total SystemTime:%ld",
                    et_total_time-st_total_time,
                    (et_total_cpu.tms_utime + et_total_cpu.tms_cutime) - (st_total_cpu.tms_utime + st_total_cpu.tms_cutime),
                    (et_total_cpu.tms_stime + et_total_cpu.tms_cstime) -(st_total_cpu.tms_stime + st_total_cpu.tms_cstime)
                    );
    CLog::PrintLog(DBG_TRACE,"%s",szData);
4

2 に答える 2

0

一般に、メモリの割り当ては比較的コストのかかる操作であるため、これがパフォーマンス クリティカルなコードである場合は、割り当てられたメモリのチャンクを確実に再利用する必要があります。

また、割り当てているメモリを削除することを忘れないでください。現在行われている様子はありません。

于 2012-05-15T09:33:26.187 に答える
0

もちろん、コードをプロファイリングすることはできますし、そうする必要がありますが、一見しただけで、次の 2 つの基本的な問題が見られます。

  1. 反復ごとにバッファを再割り当てしています。それは必要ですか、それとも同じバッファーで作業できますか? ところで、読み取る前に memset を 0 にする必要はありません。読み取った文字列の後にゼロを付けるだけです。

  2. 各反復でファイルから読み取る必要がありますか? ファイルが巨大でメモリに収まらない場合は、もちろん必要です。ファイルのサイズが比較的小さいことがわかっている場合は、それを 1 つの大きなバッファーに読み取ってから解析すると、はるかに高速になります。

于 2012-05-15T09:39:24.623 に答える