这个循环比我预期的要慢,我还不确定在哪里。看到什么了吗?
我正在使用客户端游标读取 Accces DB。当我有 20 列的 127,000 行时,这个循环大约需要 10 秒。20 列是字符串、整数和日期类型。所有类型在放入 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 可能比另一种慢。值得一试。