Tips4 CStringList への高速文字列設定方法

前のTips 次のTips


■ CStringList への文字列の設定

 CStringList を使うと、複数の行を簡単に管理出来ます。しかし、エディタ等で大量の文書 をHDDから読み込んで、CStringList オブジェクトに設定する場合、 ファイルから1行づつ読み込み、CString オブジェクトを作り、 それを設定するというコードは非常に低速で、お話しになりません。

    CStringList m_lineMgr;
    while( fgets(buffer, BUFSIZE, fo) != NULL ) {
        m_lineMgr.AddTail(CString(buffer));        //  ここが、おそい
    }

■ CString::GetBuffer を使ってバッファを直接操作する

 CString::GetBuffer により、CString オブジェクトの文字列バッファを直接操作すること ができます。メモリのアロック、フリー処理が発生しない分、高速になります(VC++では オブジェクトの構築と解放に異様に時間がかかる)。
 コードはたとえば以下のようになります(この例ではメモリマップトファイルを使って、ファイルを メモリにマップしている)。GetBuffer でバッファアドレスを取得します。この時、バッファサイズ が不足している時はリアロケートが行われます。最後に ReleaseBuffer でバッファアドレスを リリースします。

        .....
        CString rString;
        LPTSTR lpsz = rString.GetBuffer(bufSize);
        POSITION tailpos = m_lineMgr.GetTailPosition();
        while( m_ptr < m_endptr ) {
            for(const char *p = m_ptr;p < m_endptr && *p != 0x0d && *p != 0x0a; p += 1) {
                if( *p == 0x1a ) {
                    eof = 1;
                    break;
                }
            }
            int size = p - m_ptr;               //  1行の長さ
            if( eof && size == 0 )
                break;
            if( size > bufSize - 1 ) {          //  バッファサイズが足りない場合は、拡張する
                rString.ReleaseBuffer();
                lpsz = rString.GetBuffer(bufSize = size + 1);
            }
            memcpy(lpsz, m_ptr, size);          //  バッファを直接操作した方がはるかに高速!
            lpsz[size] = '\0';
            m_lineMgr.InsertBefore(tailpos, rString);       //  いつもEOFの前に挿入
            .....
        }
        rString.ReleaseBuffer();


前のTips 次のTips 津田伸秀 のホームページに戻る。

Last Updated on 24-Aug-1996, Copyright (c) 1996 by Nobuhide Tsuda, All Right Reserved.
このホームページに関するご質問、ご要望、バグレポート等は  Nobuhide_Tsuda@jsn.justnet.or.jp  までメールをいただければ幸いです。