在最佳时间内从 _variant_t 获取 char*
这是我想要加速的代码。 它从 ADO 记录集中获取一个值并将其转换为 char*。 但这很慢。 我可以跳过 _bstr_t 的创建吗?
_variant_t var = pRs->Fields->GetItem(i)->GetValue();
if (V_VT(&var) == VT_BSTR)
{
char* p = (const char*) (_bstr_t) var;
Here's the code I want to speed up. It's getting a value from an ADO recordset and converting it to a char*. But this is slow. Can I skip the creation of the _bstr_t?
_variant_t var = pRs->Fields->GetItem(i)->GetValue();
if (V_VT(&var) == VT_BSTR)
{
char* p = (const char*) (_bstr_t) var;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
BSTR 的前 4 个字节包含长度。 您可以循环遍历并获取每个其他字符(如果是 unicode)或每个字符(如果是多字节)。 某种 memcpy 或其他方法也可以。 IIRC,这可能比
W2A
或转换(LPCSTR)(_bstr_t)
更快The first 4 bytes of the BSTR contain the length. You can loop through and get every other character if unicode or every character if multibyte. Some sort of memcpy or other method would work too. IIRC, this can be faster than
W2A
or casting(LPCSTR)(_bstr_t)
您的问题(除了 _bstr_t 内内存复制的可能性之外)是您正在将 UNICODE BSTR 转换为 ANSI char*。
您可以使用在堆栈上执行转换的 USES_CONVERSION 宏,因此它们可能会更快。 或者,如果可能,将 BSTR 值保留为 unicode。
转换:
记住 - 从 OLE2A (及其姐妹宏)返回的字符串返回一个在堆栈上分配的字符串 - 从封闭范围返回,并且你有垃圾字符串,除非你复制它(显然,最终释放它)
Your problem (other than the possibility of a memory copy inside _bstr_t) is that you're converting the UNICODE BSTR into an ANSI char*.
You can use the USES_CONVERSION macros which perform the conversion on the stack, so they might be faster. Alternatively, keep the BSTR value as unicode if possible.
to convert:
remember - the string returned from OLE2A (and its sister macros) return a string that is allocated on the stack - return from the enclosing scope and you have garbage string unless you copy it (and free it eventually, obviously)
这会在堆栈上创建一个临时文件:
这使用了稍微更新的语法,并且可能更健壮。 它有一个可配置的大小,超过这个大小它将使用堆,这样就可以避免将大量字符串放入堆栈中:
This creates a temporary on the stack:
This uses a slightly newer syntax and is probably more robust. It has a configurable size, beyond which it will use the heap so it avoids putting massive strings onto the stack:
您还可以通过避免一起收集字段来加快此分配的速度。 仅当需要按名称检索项目时才应使用 Fields 集合。 如果您通过索引了解字段,则可以使用它。
注意 i 不能是整数,因为 ADO 不支持 VT_INTEGER,因此您最好使用 long 变量。
You can also make this assignment quicker by avoiding the fields collection all together. You should only use the Fields collection when you need to retrieve the item by name. If you know the fields by index you can instead use this.
Note i cannot be an integer as ADO does not support VT_INTEGER, so you might as well use a long variable.
好吧,我的 C++ 有点生疏了......但我不认为转换是你的问题。 除了告诉编译器将 _bstr_t 视为 char* 之外,该转换实际上并没有做任何事情。 然后你只需将该指针的地址分配给 p 即可。 实际上什么都没有“完成”。
您确定不仅仅是从 GetValue 获取数据速度慢吗?
或者我的 C++ 比我想象的更生锈吗?
Ok, my C++ is getting a little rusty... but I don't think the conversion is your problem. That conversion doesn't really do anything except tell the compiler to consider _bstr_t a char*. Then you're just assigning the address of that pointer to p. Nothing's actually being "done."
Are you sure it's not just slow getting stuff from GetValue?
Or is my C++ rustier than I think...