Pergunta

Aqui está o código que eu quiser acelerar. Está ficando um valor a partir de um conjunto de registros ADO e convertê-lo para um char *. Mas esta é lento. Posso ignorar a criação da _bstr_t?

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

                if (V_VT(&var) == VT_BSTR)
                {
                    char* p = (const char*) (_bstr_t) var;
Foi útil?

Solução

Os primeiros 4 bytes do BStr conter o comprimento. Você pode percorrer e obter qualquer outro personagem, se unicode ou cada personagem se multibyte. Algum tipo de método de memcpy ou outra iria trabalhar muito. IIRC, isso pode ser mais rápido do que W2A ou fundição (LPCSTR)(_bstr_t)

Outras dicas

Seu problema (que não seja a possibilidade de uma cópia de memória dentro _bstr_t) é que você está convertendo o Unicode BSTR para um caractere ANSI *.

Você pode usar as macros USES_CONVERSION que realizam a conversão na pilha, para que eles possam ser mais rápido. Como alternativa, mantenha o valor BSTR como unicode, se possível.

Para converter:

USES_CONVERSION;
char* p = strdup(OLE2A(var.bstrVal));

// ...

free(p);

lembre-se - a string retornada a partir OLE2A (e suas macros irmã) retornar uma string que é alocado na pilha - retorno do âmbito envolvente e você tem cordas de lixo a menos que você copiá-lo (e libertá-la, eventualmente, obviamente)

Isso cria um temporária na pilha:

USES_CONVERSION;
char *p=W2A(var.bstrVal);

Este utiliza uma sintaxe um pouco mais recente e é provavelmente mais robusta. Ele tem um tamanho configurável, além de que ele irá usar a pilha para que ele evita colocar cordas enormes para a pilha:

char *p=CW2AEX<>(var.bstrVal);
_variant_t var = pRs->Fields->GetItem(i)->GetValue(); 

Você também pode fazer esta tarefa mais rápido, evitando a coleção campos todos juntos. Você só deve usar o conjunto de campos quando você precisa recuperar o item pelo nome. Se você conhecer os campos de índice em vez disso pode usar isso.

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

Nota eu não posso ser um inteiro como ADO não suporta VT_INTEGER, de modo que você pode também usar uma variável longo.

Ok, meu C ++ está ficando um pouco enferrujado ... mas eu não acho que a conversão é o seu problema. Que a conversão realmente não fazer nada além de dizer ao compilador para considerar _bstr_t um char *. Então você está apenas atribuindo o endereço desse ponteiro para p. Nada está realmente a ser "feito".

Você tem certeza de que não é apenas lento recebendo o material de GetValue?

Ou é o meu enferrujado C ++ do que eu penso ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top