Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Debate Sobre C++ Y Oop

Iniciado por Jare, 19 de Diciembre de 2005, 07:44:30 PM

« anterior - próximo »

Pogacha

Cita de: "Lex"void DesplazarCadena (char * cadena, unsigned int posiciones)
{
  int i;
  int tam = strlen(cadena) - (posiciones - 1);

  if(cadena == NULL) return;

  for(i = 0; i < tam; i++)
     cadena[i] = cadena[i+posiciones];
}


Espero y creo que funciona XDDD
Lamentablemente no:

DesplazarCadena(MiCadena, - 1);

marcode

Cita de: "Lex"Dios que manía tiene la gente de usar la aritmética de punteros, cuando podrían usar el [] y sería más claro XD Además no se que problema hay con usar un int para el indice, y si te apuras usas un unsigned int, que creo que cadenas de más de 4GB no vais a encontrar por ahí, de hecho cadenas de texto de 2GB tampoco son especialmente frecuentes en memoria... Yo lo hubiera hecho así:


void DesplazarCadena (char * cadena)
{
  int i;
  int tam = strlen(cadena);

  for(i = 0; i < tam; i++)
     cadena[i] = cadena[i+1];
}
Hombre, tampoco es que yo use siempre la aritmética de punteros, y menos para tratar una simple cadena de texto, simplemente trataba un poco de llevar al extremo el ejemplo para asegurarme.

Me ha sorprendido incluso que en una prueba que he hecho con los ejemplos anteriores va igual de velocidad de las dos maneras, con punteros como con índices [], en cambio con el memcpy aumenta en muchas veces su velocidad.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

zupervaca

 La única pega que le veo es que no esta optimizado, sacrificas claridad de código por optimización, lo cual no significa que este mal, por ejemplo, poner dentro de esta función el strlen en principio a mi forma de ver las cosas no seria correcto ya que puede que fuera de la función el programador ya haya obtenido la longitud de la cadena por que haya usado otras funciones que la requieran, de hay el motivo por el cual prefiero pasárselo a la función, también al usar [] estas realizando operaciones que con aritmética de punteros no harías: direccionbase+indice*tamañoelemento, no obstante dependiendo del compilador se optimizaría o no, como consecuencia de usar [] tienes que crear otra variable para saber cuando termina la cadena, en cambio al usar punteros podrías comprobar que el contenido no fuera barra 0, 0 binario, NULL o mediante la dirección final de la cadena, la comprobación a NULL del puntero en principio no creo que importe que te la olvidaras ya que muchos programadores prefieren hacerla fuera por que después de crear varias librerías usándose entre ellas (bla bla bla) realmente no sabes si dentro se comprueba o no con lo que a veces es mejor no ponerla y ahorrarse ese if ya que el programador lo pondrá fuera, el motivo de por que lo pongo en mi código es por que esta pensado para seguridad y mas que nada por acompañar a nLength > 0, el haber puesto esta comprobación de nLength > 0 no es por seguridad, es para poder especificar la forma de comportarse la función, al poner que sea mayor a 0 la cadena que tenga una longitud de 1 hará la rotación correctamente quedando la cadena limpia, si se pusiera que fuera mayor a 1 la rotación daría error, dependiendo de que el jefe de equipo vea correcto o no que se pueda rotar una cadena de longitud 1 se pondría uno u otro valor y así no tener que tocar apenas algo de código.
Repito, esto no quiere decir que el código que hayas puesto no sea correcto, que no quiero entrar en discusiones que no llevan a ninguna parte.
He puesto previsualizar el mensaje y veo que han puesto que un valor negativo fallaría, yo me imagino que presupones al igual que yo que no se pueden hacer rotaciones en el otro sentido.
El motivo de por que el memcpy acelere mucho su velocidad es que realiza estas operaciones antes de comenzar a copiar:
- Mirar si el origen y destino están en una dirección impar, si los dos están realizar la copia del primer byte y así alienar la copia en direcciones pares de memoria que es mucho más rápido.
- Copia lo máximo posible del origen sobre el destino con una longitud múltiplo de 4. (usando el rep de asm)
- Si el tamaño que queda por copiar es 3 copia dos bytes, luego 1 y sale del memcpy.
- Si el tamaño que queda por copiar es 1 copia un byte y sale del memcpy.

seryu

 recordemos que los punteros tambien son variables..

seryu

Cita de: "Pogacha"d(char*c){while(*c)*c++=c[1];}

Me gane algo ?
Un cerdito  :P

el codigo ese es un buen ejemplo de algo que no deberia hacerse hoy dia  :D  

marcode

 El ejemplo que he puesto ni lo he usado ni tengo intención de hacerlo, ni de hacerlo lo más rapido posible, era simplemente para hacer referencia a la conveniencia o no de tratar toda la memoria de forma lineal (de ahí el uso de punteros) sin preocuparse independientemente de como ha sido creada, a propósito de este comentario que has hecho anteriormente.

Citar
Hay estas creando un array de bytes de tamaño fijo que dependiendo de uno u otro compilador puede que tengas que tener acceso a el mediante un indice ya que nadie te asegura que la memoria de ese array sea continua
Entonces me dió a entender que esto no era valido (cambiaré el ejemplo).


int DATA[10000];
int *pData=DATA;

for (int i=0;i<10000;i++)
{
*(pData++) = 0;
}


pero esto sí:


int DATA[10000];
for (int i=0;i<10000;i++)
{
DATA[i]=0;
}


yo entiendo que es tan válido uno como otro.

size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

zupervaca

Cita de: "seryu"recordemos que los punteros tambien son variables..
:blink:

pd: Me imagino que va por algo de lo que he escrito ya que va después de mi post, pero no se el que.



zupervaca

 Bueno como veo que no se entiende bien la frase que puse, mejor la explico con código que es más robótico y me resulta más sencillo expresarme así:

// Con indices
void SlideString1( char *psz, size_t nLength )
{
for( size_t i = 0; i < nLength; i++ )
{
 psz[i] = psz[i+1];
 //*(psz + i * sizeof(char)) = *(psz + (i + 1) * sizeof(char));
 /*
 El compilador cambian los [] de esta manera:
  psz[i]  -> psz + i * sizeof(char)
  psz[i+1] -> psz + (i + 1) * sizeof(char)
 Con lo que el codigo final es:
  *(psz + i * sizeof(char)) = *(psz + (i + 1) * sizeof(char));
 La mayoria de los compiladores se dan cuenta de lo
 que se esta haciendo y optimizan el codigo
 */
}
}

// Con aritmetica de punteros
void SlideString2( char *psz, size_t nLength )
{
//char *pszEnd = psz + nLength;
//while( psz != pszEnd )
while( *psz != 0 )
{
 *psz = *(psz+1);
 psz++;
}
}

Vemos que en SlideString1 hace falta más variables y operaciones matemáticas que en la función SlideString2 que al final queda muy sencilla y optimizada, para que se vuelva mas legible os recomiendo poner el código en el visual c++ u otro ide.

Referente a lo que se parte los arrays no creo que suceda actualmente, estos casos sucedían en el viejo ms-dos y los compiladores que daban soporte a mas de 64kb trabajando con este limitación igualmente, no obstante nunca me quiero arriesgar a que mi código se compile en una plataforma con este tipo de limitaciones y el compilador de soporte a esta funcionalidad, a parte los arrays de tamaño fijo suele crearse como memoria automática, es decir, se crean en la pila, cosa peligrosa si por algún casual es pequeña o se exige que sea pequeña, aunque lo dicho, actualmente estos casos no creo que se den.



zupervaca

 Haz la prueba con esta también, aunque su filosofía sea diferente veras que va más rápido aun que la creada en ensamblador por las optimizaciones que hace el memcpy. La variable pszDest debe estar creada.


void SlideString( char *psz, size_t nLength, int nSlide, char *pszDest )
{
if( psz != NULL && nLength > 0 )
{
 size_t nCount = nLength -nSlide +1;
 if( nCount > 0 )
 {
  memcpy( pszDest, psz + nSlide, nCount );
 }
}
}


Resultados en modo debug:
DesplazarCadenaExtremo: 891
DesplazarCadena: 1609
DesplazarCadenaAP: 1328
DesplazarCadenaSlide: 594

Resultados en modo release:
DesplazarCadenaExtremo: 468
DesplazarCadena: 1172
DesplazarCadenaAP: 469
DesplazarCadenaSlide: 187


sés

 La función memcpy() seguramente tiene optimizaciones que el código de arriba no tiene.

Ensamblador no significa velocidad si no se optimiza de verdad.
Soy indeciso... ¿o no?






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.