Test: C index eller pekare

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
persika
EF Sponsor
Inlägg: 1336
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Test: C index eller pekare

Inlägg av persika »

Jag har undrat vilket som är bäst att använda index array eller att använda en pekare i array'en.
Har testat på Arduino Mega 2560, Arduino IDE 1.8.16

Två loopar i testprogrammet, i första loopen tilldelas arrayen 1, 2, 3, 4...., i andra loopen summeras alla.
Tiden det tar att utföra de två looparna mäts med micros();


Så här blev resultaten:

Test med index
Sketch uses 2230 bytes of program storage space.
Global variables use 406 bytes of dynamic memory
Summa: 4950
Tid (us): 136

Test med pekare
Sketch uses 2228 bytes of program storage space.
Global variables use 406 bytes of dynamic memory.
Summa: 4950
Tid (us): 112

Fördelar och nackdelar, kommentarer ?


Andra liknande tester jag gjort tidigare:
viewtopic.php?f=43&t=85521&p=1293091#p1293091
viewtopic.php?t=81864&start=15


Programmet i sin helhet, om nån vill testa själv:

Kod: Markera allt

// Test av index eller pekare
// Arduino Mega 2560

#include <datatyper.h>
//#define IndexTest


#define AntArr 100
char* arr[AntArr];

//---------------------setup------------------------------------------
void setup() 
{
Serial.begin(9600);
uInt16 sum;
uInt32 t1;
uInt32 t2;
uInt8 a;  

t1 = micros();


#ifdef IndexTest
// test med index

// init array, med 0, 1, 2, 3...
a = 0;
while (a < AntArr)
  {
  arr[a] = a;
  a++;
  }

// summera array
a = 0;
sum = 0;
while (a < AntArr)
  {
  sum += arr[a];
  a++;
  }

#else
// test med pekare
char* p;

// init array, med 0, 1, 2, 3...
p = (void*)&arr;
a = 0;
while (a < AntArr)
  {
  *p = a;
  p++;
  a++;
  }

// summera array
p = (void*)&arr;
a = 0;
sum = 0;
while (a < AntArr)
  {
  sum += *p;
  p++;
  a++;
  }

#endif

t2 = micros();
Serial.print("Summa: ");
Serial.println(sum);
Serial.print("Tid (us): ");
Serial.println(t2-t1);
}
//---------------------setup------------------------------------------


//---------------------loop-------------------------------------------
void loop() 
{
}
//---------------------loop-------------------------------------------
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: Test: C index eller pekare

Inlägg av hawkan »

Ja nu blir det ett tråkigt svar men låt kompilatorn optimera koden och du skriver den på det sätt du förstår bäst och som är lättast för dej att debugga.
persika
EF Sponsor
Inlägg: 1336
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Re: Test: C index eller pekare

Inlägg av persika »

Inget tråkigt svar.
Läsbarhet och förståelse av ett program är betydelsefullt. Oftast har man inte så bråttom, så yttersta prestanda har inte så stor betydelse, men det är bra att veta lite vad som sker ”under motorhuven ”. Även bra att ha kännedom om pekare och hur de funkar.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Test: C index eller pekare

Inlägg av sodjan »

Notera också att index varianten fungerar oavsett storleken på varje element i arrayen.
I pekar fallet så måste "pekar-aritmetiken" ta hänsyn till det, det räcket inte att bara plussa med ett.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Test: C index eller pekare

Inlägg av Mr Andersson »

Bägge fallen fungerar likadant.
pekare + x görs om av kompilatorn till pekare + x * sizeof(datatyp)
arr[3] är identiskt med *(arr + 3) oavsett underliggande typ. Men den första varianten är mer lättförståelig.
Om datatypen är okänd (ie void*) så kommer kompilatorn inte godkänna koden.
agehall
Inlägg: 418
Blev medlem: 12 augusti 2020, 19:27:54

Re: Test: C index eller pekare

Inlägg av agehall »

sodjan skrev: 9 juni 2023, 10:19:51 I pekar fallet så måste "pekar-aritmetiken" ta hänsyn till det, det räcket inte att bara plussa med ett.
Nej, det stämmer inte - som redan påpekats så ökas pekaren med sizeof(datatyp) när man lägger på 1. Dock så råkar det ju bara bli rätt här eftersom array:en innehåller char* (vilket känns helt fel på alla sätt) och pekaren som används är char* (och casta:s via void* för att undvika kompileringsfel!) istället för char**. Hade arrayen bestått av en struct med flera element så hade det knappast blivit rätt.

Ypperligt exempel på varför C är svårt och varför man måste ha koll på hur pekare fungerar.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Test: C index eller pekare

Inlägg av sodjan »

Det var lite så jag menade, det *råkar* bli "rätt" tack vara att det är "enkla" array element.
Första exemplet med array index blir dock alltid rätt.

Om du hade citerat båda mina rader så hade sammanhanget framgått.

> Notera också att index varianten fungerar oavsett storleken på varje element i arrayen.
> I pekar fallet så måste "pekar-aritmetiken" ta hänsyn till det, det räcket inte att bara plussa med ett.
agehall
Inlägg: 418
Blev medlem: 12 augusti 2020, 19:27:54

Re: Test: C index eller pekare

Inlägg av agehall »

Sorry, jag läste ditt inlägg lite fel. Jag var redan så upprörd över de grundläggande felen i koden så jag misstolkade det du skrev. Pekarvarianten av koden är ett riktigt fint exempel på hur man INTE ska koda C.
bearing
Inlägg: 11232
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Test: C index eller pekare

Inlägg av bearing »

Skillnaden var så liten att det inte är värt att bekymra sig över vilken kod som är snabbast.

Arduino har väl som standard en ganska hög optimeringsgrad av GCC, vilket betyder att den normalt skapar bra maskinkod av C-koden.

Om man däremot kompilerar med GCC helt o-optimerat (-O0) blir maskinkoden betydligt större och långsammare. En faktor 2-4 enligt min erfarenhet. Har läst att GCC är en speciell kompilator som ger betydligt större skillnad mellan -O0 och -O1 än andra kompilatorer. Många andra kompilatorer utför nämligen normalt ungefär samma optimering som GCC med -O1 när kompilatorn anropas utan optimering.
SvenW
Inlägg: 1116
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Re: Test: C index eller pekare

Inlägg av SvenW »

Det förvånar mig att det blev någon skillnad alls.
Men optimeringen var kanske avstängd? Och vilken kompilator var det?
bearing
Inlägg: 11232
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Test: C index eller pekare

Inlägg av bearing »

Antagligen avr-gcc som används av Arduino-miljön för AVR-processorerna. Har -Os som standard har jag för mig.

Här en artikel jag läst tidigare om de olika -O flaggorna till avr-gcc
https://www.elektormagazine.com/labs/ar ... aller-code

Jag har jobbat lite med att snabba upp program till AVR och avr-gcc, och då märkte jag också att det gick en aning snabbare att använda pekare istället för array-indexering. Det beror på att när man använder pekaren används oftast indexeringsregistret direkt, medan när man addresserar via array-index, måste den vid varje operation addera indexet för array[0] med det index man är intresserad av, så det blir en extra ADD för varje varv i loopen i princip.
Skriv svar