c++ - 你认为是什么让这个 C++ 代码变慢了? (它循环遍历 ADODB 记录集,将 COM 类型转换为字符串,并填充 ostringstream)

标签 c++ com stl adodb

这个循环比我预期的要慢,我还不确定在哪里。看到什么了吗?

我正在使用客户端游标读取 Accces 数据库。当我有 127,000 行和 20 列时,这个循环大约需要 10 秒。 20列分别是string、int、date类型。所有类型在放入 ostringstream 缓冲区之前都会转换为 ANSI 字符串。

void LoadRecordsetIntoStream(_RecordsetPtr& pRs, ostringstream& ostrm)
{
    ADODB::FieldsPtr pFields = pRs->Fields;
    char buf[80];
    ::SYSTEMTIME sysTime;
    _variant_t var;

    while(!pRs->EndOfFile) // loop through rows
    {
        for (long i = 0L; i < nColumns; i++)  // loop through columns
        {

            var = pFields->GetItem(i)->GetValue();

            if (V_VT(&var) == VT_BSTR)
            {
                ostrm << (const char*) (_bstr_t) var;   
            }
            else if (V_VT(&var) == VT_I4
            || V_VT(&var) == VT_UI1
            || V_VT(&var) == VT_I2
            || V_VT(&var) == VT_BOOL)
            {
                ostrm << itoa(((int)var),buf,10);
            }
            else if (V_VT(&var) == VT_DATE)
            {
                ::VariantTimeToSystemTime(var,&sysTime);
                _stprintf(buf, _T("%4d-%02d-%02d %02d:%02d:%02d"),
                sysTime.wYear, sysTime.wMonth, sysTime.wDay, 
                sysTime.wHour, sysTime.wMinute, sysTime.wSecond);

                ostrm << buf;
            }
        }

        pRs->MoveNext();
    }
}

编辑:经过更多实验...

我现在知道大约一半的时间被这条线占用了:
var = pFields->GetItem(i)->GetValue();

如果我绕过 Microsoft 生成的 COM 包装器,我的代码会更快吗?我的猜测是否定的。

另外一半时间花在转换数据并将其流式传输到 ostringstream 的语句上。

在撰写本文时,我现在不知道是转化还是流媒体花费了更多时间。

如果我不使用 ostringstream 而是管理我自己的缓冲区,使用我自己的逻辑来增加缓冲区(重新分配、复制、删除),会不会更快?如果我的逻辑做出悲观的猜测并预先为 ostringstream 缓冲区预留大量空间,会不会更快?这些可能是值得尝试的实验。

最后,转化本身。在我的时间安排中,这三个都不是很糟糕。一个答案说我的 itoa 可能比替代方案慢。值得一试。

最佳答案

我无法通过查看您的代码来判断,更熟悉 COM/ATL 的人可能会有更好的答案。

通过尝试 n 次错误,我会通过注释掉内部循环操作来找到缓慢的代码,直到您看到性能峰值,然后您就有了罪魁祸首,应该专注于此。

关于c++ - 你认为是什么让这个 C++ 代码变慢了? (它循环遍历 ADODB 记录集,将 COM 类型转换为字符串,并填充 ostringstream),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/271204/

相关文章:

c++ - 在 ATL 项目中将 NULL 指针传递给进程外 COM 方法的正确方法

c++ - C++模板特化的思考

c++ - 在 C++ 中,我怎样才能从一个对象到一个静态成员?

C++:是否有一种有效的方法来在句法上使用像指针这样的索引?

c# - System.Windows.Automation非常慢

com - 为什么我们必须为 idl 中的每个接口(interface)创建唯一的 uuid?

c++ - 使用 STL 算法进行 vector 操作

c++ - 标准库 to_string(double) 在 vs2015 中给出了错误的值。有什么解决办法吗?

c++ - 检查是否可以使用 strtod 将字符串转换为 double

c++ - 打开场景图 LNK2019 错误