Newsgroup: it.comp.os.linux.development
Titolo: [XPOST] [C] Efficienza puntatori Vs array

[xpost and followup-to: it.comp.os.linux.development]
Ciao a tutti! :)
Volevo capire se, in linguaggio C su Linux, fosse piu' efficiente
(veloce) l'accesso ad una stringa attraverso:
1) Puntatori
char str[]="hello";
char* pstr;
pstr = str;
// diversi accessi tipo "*pstr"
2) Array
char str[]="hello";
// diversi accessi tipo "str[i]"
Ho scritto quindi un (semplice e brutale!) codice [1] che mi calcolasse
i tempi di accesso ad una stringa sulla base dei due precedenti metodi
ed in diverse varianti.
La piattaforma da me usata e' composta da:
- compilatore gcc
- Kernel linux 2.4
- Distribuzione Knoppix 3.2
- Hardware intel Pentium 4 M 1.8 Ghz, 256 MB di RAM
RISULTATO (in breve): l'accesso tramite array sembra il piu' veloce!
Quali i vostri commenti?
Spero in una discussione costruttiva :)
[1]CODICE
#include <stdio.h>
#include <string.h>
#include <time.h>
strcopy1(char s1[],char s2[])
{
int x;
for (x=0; x<=strlen(s2); x++)
{
s1[x]=s2[x];
}
}
strcopy2(char s1[],char s2[])
{
int x;
int y = strlen(s2);
for (x=0; x<=y; x++)
s1[x]=s2[x];
}
strcopy3(char s1[],char s2[])
{
int x;
int y = strlen(s2);
for (x=0; s2[x]==0; x++)
s1[x]=s2[x];
}
strcopy4(char* s1, char* s2)
{
while(*s2 != '\0')
{
*s1 = *s2;
s1++;
s2++;
}
}
strcopy5(char* s1, char* s2)
{
while(*s2)
*s1++=*s2++;
}
strcopy6(char* s1, char* s2)
{
while(*s1++=*s2++);
}
main(int argc, char *argv[])
{
double interval;
time_t start;
time_t finish;
char* pstring1;
char* pstring2;
long int i = 1;
const int bound = 10000000;
char string2[] = "I'm testing the speed of execution of strcpy. I'm
testing the speed of execution of strcpy. I'm testing the speed of
execution of strcpy.";
char string1[200];
pstring1 = string1;
pstring2 = string2;
//STRCOPY1
time(&start);
while (i<bound)
{
strcopy1(string1,string2);
i++;
}
time(&finish);
interval = difftime(finish,start);
printf("\n");
printf("STRCPY1: ");
printf("%f", interval);
printf("\n");
string1[0]='\0';
i=1;
//STRCOPY2
time(&start);
while (i<bound)
{
strcopy2(string1,string2);
i++;
}
time(&finish);
interval = difftime(finish,start);
printf("\n");
printf("STRCPY2: ");
printf("%f", interval);
printf("\n");
string1[0]='\0';
i=1;
//STRCOPY3
time(&start);
while (i<bound)
{
strcopy3(string1,string2);
i++;
}
time(&finish);
interval = difftime(finish,start);
printf("\n");
printf("STRCPY3: ");
printf("%f", interval);
printf("\n");
string1[0]='\0';
i=1;
//STRCOPY4
time(&start);
while (i<bound)
{
strcopy4(pstring1,pstring2);
i++;
}
time(&finish);
interval = difftime(finish,start);
printf("\n");
printf("STRCPY4: ");
printf("%f", interval);
printf("\n");
string1[0]='\0';
i=1;
//STRCOPY5
time(&start);
while (i<bound)
{
strcopy5(pstring1,pstring2);
i++;
}
time(&finish);
interval = difftime(finish,start);
printf("\n");
printf("STRCPY5: ");
printf("%f", interval);
printf("\n");
string1[0]='\0';
i=1;
//STRCOPY6
time(&start);
while (i<bound)
{
strcopy6(pstring1,pstring2);
i++;
}
time(&finish);
interval = difftime(finish,start);
printf("\n");
printf("STRCPY6: ");
printf("%f", interval);
printf("\n");;
string1[0]='\0';
i=1;
//STRCOPY7
time(&start);
while (i<bound)
{
strcpy(pstring1,pstring2);
i++;
}
time(&finish);
interval = difftime(finish,start);
printf("\n");
printf("STRCPY7: ");
printf("%f", interval);
printf("\n");;
string1[0]='\0';
i=1;
}
OUTPUT
TEMPI (in secondi):
STRCPY1: 531.000000
STRCPY2: 12.000000
STRCPY3: 4.000000
STRCPY4: 7.000000
STRCPY5: 6.000000
STRCPY6: 10.000000
STRCPY7: 3.000000
-- 
Il Prof.

 (veloce) l'accesso ad una stringa attraverso:
piuttosto che fare le misure così usa un profiler, come gprof o oprofile.
e perché non usi una memcpy? tu lo obblighi a copiare byte a byte, e non
è sempre la soluzione migliore.

 Spero in una discussione costruttiva :)
Mah... secondo me il test non ha nessuna conclusione definitiva.
Troppe le variabili non considerate. Ad esempio, quante volte hai 
eseguito il test? Dovresti ripeterelo almeno un centinaio di volte per 
avere una media dei tempi.
Poi nessuno ci dice come è implementata la strcpy che usi al settimo 
test. Presumo sia quella di libreria, che probabilmente è già super 
ottimizzata se non addirittura scritta in assembly.
JM2C ;)
Martino
-- 
Se non conosci la netiquette o il quoting,
ti prego, prima di rispondere, leggi qui:
http://www.marco5x.net/usenet/galateo.php
http://www.marco5x.net/usenet/quoting.php

e perché non usi una memcpy? 
Provero' entrambi i consigli! :)
-- 
Il Prof.

JM2C ;)
Grazie! :)
-- 
Il Prof.

 other less alarmist word?
"screwed" -- Alexander Viro

 }
Il ciclo dovrebbe essere:
  for (x=0; s2[x] != 0; x++) 
    s1[x]=s2[x];
Con la versione corretta della funzione 3, sembrerebbe piu` veloce
l'accesso tramite puntatore, pero` i due gruppi di funzioni usano
algoritmi diversi: alcune prima calcolano la lunghezza della stringa e
poi copiano, altre copiano fino al carattere nullo.
Per un confronto puntatori/indici bisogna usare lo stesso algoritmo
cambiando solo il metodo di accesso agli array.
        Mauro

cold cache.
Sorry...ma cosa intendi?
Grazie mille degli spunti di riflessione! :)
-- 
Il Prof.

cambiando solo il metodo di accesso agli array.
Anche qui ti do ragione...sbagliando si impara :)
-- 
Il Prof.

 Le prime 2 implementazioni sono identiche tra loro, 
Nella prima strlen viene richiamata tutte le volte, nella seconda una
volta sola all'inizio, quindi non sono equivalenti e il tempo
esagerato della prima versione sicuramente e` dovuto a questa
differenza.
Il compilatore puo` ottimizzare la prima versione solo se:
1- sa che strlen, se chiamata con lo stesso argomento restituisce
sempre lo stesso risultato (deve essere uguale l'array e non solo il
puntatore);
(2) sa che l'array puntato da s2 non viene modificato nel ciclo.
La condizione (1) potrebbe verificarsi (strlen e` una funzione
standard nota al compilatore) anche se non penso che il gcc arrivi a
questo punto.
La (2) e` impossibile senza una analisi di tutto il programma: per
quello che ne sa il compilatore la funzione potrebbe essere chiamata
come:
  strcopy2(s+1, s);
e in questo caso strlen(s2) cambia ogni volta.
        Mauro

 Scusa l'ingnoranza ma non vedo le due scansioni.
strlen()
Luca
-- 
Home: 
http://kronoz.cjb.net
42

 ha scritto nel messaggio
news:cqb4h0933sbhuol6n...@4ax.com...
