最適な時間で _variant_t から char* を取得する
-
02-07-2019 - |
質問
高速化したいコードは次のとおりです。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;
解決
BSTR の最初の 4 バイトには長さが含まれます。ループして、Unicode の場合は 1 文字おきに、マルチバイトの場合はすべての文字を取得できます。ある種の memcpy または他の方法も機能するでしょう。IIRC、これは W2A
またはキャスト (LPCSTR)(_bstr_t)
他のヒント
あなたの問題 (_bstr_t 内のメモリコピーの可能性を除く) は、UNICODE BSTR を ANSI char* に変換していることです。
スタック上で変換を実行する USES_CONVERSION マクロを使用できるため、より高速になる可能性があります。あるいは、可能であれば BSTR 値を Unicode のままにしてください。
変換する:
USES_CONVERSION;
char* p = strdup(OLE2A(var.bstrVal));
// ...
free(p);
覚えておいてください - OLE2A (およびその姉妹マクロ) から返される文字列は、スタックに割り当てられている文字列を返します - 囲んでいるスコープから返されると、それをコピーしない限り (当然、最終的には解放されますが) ガベージ文字列が残ります。
これにより、スタック上に一時ファイルが作成されます。
USES_CONVERSION;
char *p=W2A(var.bstrVal);
これは少し新しい構文を使用しており、おそらくより堅牢です。サイズは設定可能で、それを超えるとヒープが使用されるため、スタックに大量の文字列が置かれることがなくなります。
char *p=CW2AEX<>(var.bstrVal);
_variant_t var = pRs->Fields->GetItem(i)->GetValue();
フィールドを一度に収集しないようにすることで、この割り当てをより迅速に行うこともできます。Fields コレクションは、項目を名前で取得する必要がある場合にのみ使用してください。インデックスによってフィールドがわかっている場合は、代わりにこれを使用できます。
_variant_t vara = pRs->Collect[i]->Value;
ADO は VT_INTEGER をサポートしていないため、i は整数にはできないことに注意してください。したがって、long 変数を使用することもできます。
さて、私の C++ は少し錆びてきています...しかし、変換はあなたの問題ではないと思います。この変換では、コンパイラーに _bstr_t を char* とみなすように指示する以外、実際には何も行われません。次に、そのポインタのアドレスを p に割り当てるだけです。実際には何も「完了」していません。
GetValue からの取得が遅いだけではないでしょうか?
それとも、私の C++ は思っているよりも錆びているのでしょうか...