Domanda

Ecco il codice che voglio velocizzare. Sta ottenendo un valore da un recordset ADO e convertendolo in un carattere *. Ma questo è lento. Posso saltare la creazione di _bstr_t?

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

                if (V_VT(&var) == VT_BSTR)
                {
                    char* p = (const char*) (_bstr_t) var;
È stato utile?

Soluzione

I primi 4 byte del BSTR contengono la lunghezza. È possibile eseguire il ciclo continuo e ottenere tutti gli altri personaggi se Unicode o tutti i personaggi se multibyte. Funzionerebbe anche una sorta di memcpy o altri metodi. IIRC, questo può essere più veloce di W2A o lanciare (LPCSTR)(_bstr_t)

Altri suggerimenti

Il tuo problema (oltre alla possibilità di una copia di memoria all'interno di _bstr_t) è che stai convertendo UNICODE BSTR in un carattere ANSI *.

Puoi utilizzare le macro USES_CONVERSION che eseguono la conversione nello stack, quindi potrebbero essere più veloci. In alternativa, mantenere il valore BSTR come unicode, se possibile.

per convertire:

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

// ...

free(p);

ricorda - la stringa restituita da OLE2A (e le sue macro gemelle) restituiscono una stringa che è allocata nello stack - ritorna dall'ambito che racchiude e hai una stringa di immondizia a meno che non la copi (e alla fine, ovviamente, ovviamente)

Questo crea un temporaneo nello stack:

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

Questo utilizza una sintassi leggermente più recente ed è probabilmente più robusto. Ha una dimensione configurabile, oltre la quale utilizzerà l'heap in modo da evitare di mettere enormi stringhe nello stack:

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

Puoi anche rendere questo compito più veloce evitando la raccolta dei campi tutti insieme. Utilizzare la raccolta Campi solo quando è necessario recuperare l'elemento per nome. Se conosci i campi per indice, puoi invece utilizzare questo.

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

Nota che non posso essere un numero intero poiché ADO non supporta VT_INTEGER, quindi potresti anche utilizzare una variabile lunga.

Ok, il mio C ++ sta diventando un po 'arrugginito ... ma non credo che la conversione sia un tuo problema. Quella conversione in realtà non fa altro che dire al compilatore di considerare _bstr_t un carattere *. Quindi stai solo assegnando l'indirizzo di quel puntatore a p. In realtà non viene fatto nulla "quot."

Sei sicuro che non sia solo lento ottenere cose da GetValue?

O il mio C ++ è più pericoloso di quanto penso ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top