Получение символа* из _variant_t в оптимальное время

StackOverflow https://stackoverflow.com/questions/117755

Вопрос

Вот код, который я хочу ускорить.Он получает значение из набора записей ADO и преобразует его в символ *.Но это происходит медленно.Могу ли я пропустить создание _bstr_t?

                _variant_t var = pRs->Fields->GetItem(i)->GetValue();

                if (V_VT(&var) == VT_BSTR)
                {
                    char* p = (const char*) (_bstr_t) var;
Это было полезно?

Решение

Первые 4 байта BSTR содержат длину.Вы можете перебирать и получать все остальные символы в юникоде или каждый символ в многобайтовом формате.Какой-нибудь 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(); 

Вы также можете ускорить это назначение, избегая сбора всех полей вместе.Вы должны использовать коллекцию полей только тогда, когда вам нужно получить элемент по имени.Если вы знаете поля по индексу, вы можете вместо этого использовать это.

_variant_t vara = pRs->Collect[i]->Value;

Обратите внимание, что i не может быть целым числом, так как ADO не поддерживает VT_INTEGER, поэтому вы также можете использовать длинную переменную.

Ладно, мой C ++ становится немного ржавым...но я не думаю, что конверсия - это ваша проблема.Это преобразование на самом деле ничего не делает, кроме указания компилятору считать _bstr_t символом *.Затем вы просто присваиваете адрес этого указателя p .На самом деле ничего не "делается".

Вы уверены, что это не просто медленное получение данных из GetValue?

Или мой C ++ более ржавый, чем я думаю...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top