ファイルおよび文字列操作のスピードについて

[戻る]
てんてく 2008/07/02(水) 16:51:07
お世話になってます
最近、VC6.0からVS2008に移行しているのですが
テキストファイルからデータを読み出すスピードがあからさまに
遅くなってしまいました。該当アプリで
3〜4秒程度→1分超え
MBCSにすると少しだけ早くなるようですがそれでも1分はかかっています。
ファイルサイズは合計4Mくらい、使用しているのは
カスタムしたCStdioFile(C, C++のコメント書式の文字を読み飛ばす),
CStdioFile::ReadString,
CString::Find,
_stscanf,
CString::operator==

なにか良い解決方法はあるでしょうか?

PATIO 2008/07/02(水) 17:45:15
VS2008のEditionがわかりませんが、プロファイルが取れるEditionなら
プロファイルを取って見てはいかがでしょう?
それでどの部分が大幅に遅くなっているのか予想できないでしょうか?

無いとは思いますが、DebugとReleaseで比較したりとかはして無いですよね。

てんてく 2008/07/03(木) 17:14:54
http://www.cycleof5th.com/tips/index.php?date=2007-12-26
を参考にプロファイルを取ってみましたが
                                     entry  static       dynamic     %     run
関数名                                  count   instr         instr  total   
total
SpeedTest                                1     113       2623508   87.9   87.9
ATL::operator==                      51490       9        360430   12.1  100.0
CSpeedTestDlg::OnInitDialog              1      43            43    0.0  100.0
CSpeedTestApp::InitInstance              1      27            27    0.0  100.0
...

SpeedTestというのはデータ取り込みの一部を抜粋したものですが
この関数が遅いっていうレベルまではもともとわかっている・・・。
指定した関数内でのプロファイルが取れればいいのですが
やり方がわかりませんでした

timeGetTime,GetTickCountなどを使用して実アプリの方で測ってみた結果、
カスタムReadString 504 -> 1609
_stscanf 200 -> 683
ほかデータ取り込み 686 -> 63189

まだまだ割り出しは&修正が必要ですが標準のものまでが遅くなっているので
これらについて情報があったらお願いします

2008/07/05(土) 03:55:34
最適化のオプションが切れているor大幅に違うって事は無いですか?
標準の関数まで低速化しているとなると全体に影響する設定が疑わしいのです
が・・・

アセンブリ言語が多少なりとも読めるのであれば、アセンブリ言語で出力して速
度差の顕著な関数のコードの違いを確認してみると良いかと思います。
コンパイルオプションから出力すると他の設定に干渉しそうな気もするので、.obj
ファイルをVC付属のDUMPBINに/DISASMオプション付きで放り込むなどのほう
が簡単に見えると思います。

ITO 2008/07/05(土) 09:18:23
両方ともMFCでOSはWindowsXPてことですか?
VS2008のOSがvistaってことはないですよね。

てんてく 2008/07/07(月) 11:42:12
アセンブラは読めないですが・・・。
何とか確認してみようと思います。
OSはXPで同じPC上で実行していますので
開発環境以外の差はないものと思ってください。(MFCは使用)
また、仮に

void FileTest(LPCTSTR fname)
{
    DWORD d1 = GetTickCount();
    CStdioFile f;

    CString s1, s2;
    if(f.Open(fname, CFile::modeRead|CFile::typeText))
    {
        while(f.ReadString(s1))
        {
            int ct = 0;
            while(true == AfxExtractSubString(s2, s1, ct, ','))
            {    //    データ取り込み、仮
                ++ct;
            }
        }
    }
    DWORD d2 = GetTickCount();
#if _DEBUG
    TRACE1("%d\n", d2-d1);
#else
    s1.Format(_T("%d"), d2-d1);
    ::AfxMessageBox(s1);
#endif
}

2M程度のテキストファイルがあったとしてこのコードを実行すると
ファイルにも因りますがそれなりに違いがあります。
皆様の環境ではどうなりますか?
最適化というよりも文字列ライブラリが重たくなってるような・・?

玲音 (st.lain) 2008/07/07(月) 13:46:27
コード読んでいませんのであしからず。

> 皆様の環境ではどうなりますか?
各エディションでのオプション統一が面倒なので、以下の点だけは確認しました。
・プロジェクトは「Win32コンソールアプリ」から、MFCのみ有効
・文字コードはUNICODE
・MFCは共有ライブラリ

テスト環境
OS: Windows XP Professional SP2
VC++: 6.0(SP6), 2003(SP1), 2008(SP1 beta)
File: SQL Server 2005のインストールログ (S-JIS, 9.6MB)
 
結果 (Release)
VC++6.0 → 219
VC++2003 → 796
VC++2008 → 2094

単純に時間が増えた〜とは言えません(コード内部を見ていませんし、コンパイル
オプションが異なっているとも限らないので)。が、ファイル読み込みなどにバッファ
オーバーラン対策などが追加されて遅くなったとも言い切れないような気もします。

これらの結果からてんてくさんが遭遇されているような重さになるのか、
もわかりません。コツコツ調べるしかないのカモ。


参考にならないデータとして捉えてください orz

てんてく 2008/07/09(水) 09:11:42
[[解決]]
MBCSにすると少々早くなると思いますが・・・どうでしょう

解決はしていませんが、7月末くらいまで別の仕事を入れられてしまったので
一旦閉めたいと思います。何かわかったことがあったらまたよろしくお願いします。

古いスレッドには追加発言できません。