我正在比较MFC类之间的性能:

  • CFile + CArchive(使用缓冲区)


  • CStdioFile(使用缓冲的I / O流)

  • 两者都使用缓冲区。

    以下是我的代码:
    void TestFun1(CFile& File, BOOL bIsMemFile)
    {
        CArchive Archive(&File, CArchive::store);
        CString strLine, strOutput;
        UINT uSize;
        BYTE* lpBuf;
    
        ULONGLONG uStart, uStop;
    
        uStart = ::GetTickCount64();
    
        for (UINT nIndex = 0; nIndex < 500; nIndex ++)
        {
            //  Reset the file to empty
            File.SetLength(0);
    
            strLine.Format(_T("This is line %u."), nIndex);
    
            for (UINT j = 0; j < 5000; j++)
                File.Write((LPCTSTR)strLine, strLine.GetLength() * sizeof(TCHAR));
    
            File.Flush();
        }
    
        uStop = ::GetTickCount64();
    
        CString strMsg;
    
        strMsg.Format(_T("Total time(TestFun1): %I64u."), uStop - uStart);
        AfxMessageBox(strMsg);
    }
    
    void TestFun2(CFile& File, BOOL bIsMemFile)
    {
        CArchive Archive(&File, CArchive::store);
        CString strLine, strOutput;
        UINT uSize;
        BYTE* lpBuf;
    
        ULONGLONG uStart, uStop;
    
        uStart = ::GetTickCount64();
    
        for (UINT nIndex = 0; nIndex < 500; nIndex ++)
        {
            //  Reset the file to empty
            File.SetLength(0);
    
            strLine.Format(_T("This is line %u."), nIndex);
    
            for (UINT j = 0; j < 5000; j++)
                Archive.WriteString(strLine);
    
            Archive.Flush();
        }
    
        uStop = ::GetTickCount64();
    
        CString strMsg;
    
        strMsg.Format(_T("Total time(TestFun2): %I64u."), uStop - uStart);
        AfxMessageBox(strMsg);
    }
    
    void CTestMemFileDlg::OnBnClickedButton1()
    {
        // TODO: Add your control notification handler code here
        CFile File;
        CMemFile MemFile;
    
        if (File.Open(_T("E:\\Temp\\testfile.dat"), CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone))
        {
            TestFun1(File, FALSE);
            TestFun2(File, FALSE);
            TestFun1(File, FALSE);
            TestFun2(File, FALSE);
    
            File.Close();
        }
    }
    
    void CTestMemFileDlg::OnBnClickedButton2()
    {
        // TODO: Add your control notification handler code here
        CStdioFile File;
        CMemFile MemFile;
    
        if (File.Open(_T("E:\\Temp\\testfile.dat"), CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone))
        {
            int nVal;
    
            nVal = setvbuf(File.m_pStream, NULL, _IOFBF, 1024768);
    
            TestFun1(File, FALSE);
            TestFun2(File, FALSE);
            TestFun1(File, FALSE);
            TestFun2(File, FALSE);
    
            File.Close();
        }
    }
    

    结果是:

    按钮1:
    TestFun1: 18174
    TestFun2: 375
    TestFun1: 18330
    TestFun2: 375
    

    Button2:
    TestFun1: 546
    TestFun2: 530
    TestFun1: 530
    TestFun2: 531
    

    根据我的测试,CFile + CArchive始终花费CStdioFile大约66%的时间。我尝试将CS​​tdioFile的缓冲区增加到1MB,但仍然得到相同的结果。

    因此,我的问题是,由于两种解决方案都使用缓冲,为什么CStdioFile总是比CFile + CArchive慢?

    最佳答案

    CStdioFile默认情况下以文本模式打开文件。这会导致特殊字符的翻译,例如回车符和换行符,这显然需要时间。

    如果要避免这种情况,可以在CFile::typeBinary调用中将nOpenFlags添加到CStdioFile::open()参数中。

    关于c++ - 为什么CFile + CArchive的性能优于C I/O流?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56927022/

    10-09 03:06