这个循环比我预期的要慢,我还不确定在哪里。看到什么了吗?
我正在使用客户端游标读取 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/