Pregunta

Aquí está el código que quiero acelerar.Obtiene un valor de un conjunto de registros ADO y lo convierte a un carácter *.Pero esto es lento.¿Puedo omitir la creación del _bstr_t?

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

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

Solución

Los primeros 4 bytes del BSTR contienen la longitud.Puede recorrer y obtener todos los demás caracteres si es Unicode o todos los caracteres si son multibyte.Algún tipo de memcpy u otro método también funcionaría.IIRC, esto puede ser más rápido que W2A o casting (LPCSTR)(_bstr_t)

Otros consejos

Su problema (aparte de la posibilidad de una copia de memoria dentro de _bstr_t) es que está convirtiendo UNICODE BSTR en un carácter ANSI*.

Puede utilizar las macros USES_CONVERSION que realizan la conversión en la pila, por lo que podrían ser más rápidas.Como alternativa, mantenga el valor BSTR como Unicode si es posible.

para convertir:

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

// ...

free(p);

recuerde: la cadena devuelta por OLE2A (y sus macros hermanas) devuelve una cadena que está asignada en la pila; regrese desde el ámbito adjunto y tendrá una cadena basura a menos que la copie (y la libere eventualmente, obviamente)

Esto crea un temporal en la pila:

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

Esto utiliza una sintaxis ligeramente más nueva y probablemente sea más sólida.Tiene un tamaño configurable, más allá del cual usará el montón para evitar colocar cadenas masivas en la pila:

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

También puedes hacer esta tarea más rápida evitando la recopilación de campos por completo.Solo debes usar la colección Fields cuando necesites recuperar el elemento por nombre.Si conoce los campos por índice, puede utilizar esto.

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

Tenga en cuenta que no puedo ser un número entero ya que ADO no admite VT_INTEGER, por lo que también podría utilizar una variable larga.

Ok, mi C++ se está oxidando un poco...pero no creo que la conversión sea tu problema.Esa conversión realmente no hace nada excepto decirle al compilador que considere _bstr_t un carácter*.Entonces simplemente estás asignando la dirección de ese puntero a p.En realidad no se está "haciendo nada".

¿Estás seguro de que no es simplemente lento obtener cosas de GetValue?

¿O mi C++ está más oxidado de lo que creo...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top