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
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.
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.
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.
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.
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.
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.
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.
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.
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.