Loop- och calldata-trick
Billigare operationer
Loop- och calldata-trick är en gratis lektion i Grunderna i Web3- och DApp-utveckling på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Grunderna i Web3- och DApp-utveckling, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Grunderna i Web3- och DApp-utveckling innehåller totalt 4 lektioner.
Loopar multiplicerar kostnaden
Loopar är riskabla med avseende på gas, eftersom varje operation inuti körs en gång per iteration. Ett enda dyrt anrop i en loop kan överskrida Er gasbudget eller nå blockets gasgräns.
Målet är att flytta så mycket arbete som möjligt utanför loopen och göra varje iteration så billig som möjligt.
Cacha längden
Att läsa array.length i en lagringsarray kostar en SLOAD varje gång loopvillkoret kontrolleras. Cacha längden i en lokal variabel innan loopen.
// BAD: SLOAD on every iteration
for (uint256 i = 0; i < items.length; i++) { }
// GOOD: one SLOAD
uint256 len = items.length;
for (uint256 i = 0; i < len; i++) { }Undvik lagring i loopar
Läs aldrig från eller skriv till samma lagringsslot upprepade gånger i en loop. Ackumulera i en lokal variabel och skriv resultatet en gång efter att loopen har avslutats.
// GOOD: single storage write after the loop
uint256 total = 0;
for (uint256 i = 0; i < len; i++) {
total += amounts[i];
}
balance = total; // one SSTOREOkontrollerad inkrementering
Sedan Solidity 0.8 har aritmetik inbyggda overflow-kontroller som kostar extra gas. En loopräknare som realistiskt sett aldrig kan orsaka overflow kan inkrementeras i ett unchecked-block.
for (uint256 i = 0; i < len;) {
// loop body
unchecked { ++i; }
}Preinkrementering framför postinkrementering
++i är marginellt billigare än i++, eftersom postinkrementering måste skapa en tillfällig kopia av det gamla värdet. Besparingen per operation är liten, men den ackumuleras över många iterationer.
Föredra ++i för loopräknare när returvärdet inte används.
for (uint256 i = 0; i < len; ++i) {
// ++i avoids a temporary copy
}Calldata framför memory
För externa funktioner undviker ni att kopiera data till minnet genom att deklarera array- och struct-parametrar som calldata i stället för memory. Calldata är skrivskyddad och billigare att läsa.
// Cheaper: no memory copy
function process(uint256[] calldata data) external {
for (uint256 i = 0; i < data.length; ++i) { }
}Minska calldata
Varje calldata-byte som inte är noll kostar 16 gas. Mindre nyttolaster innebär billigare transaktioner. Tekniker omfattar:
- Packa flera värden i en
uint256 - Använd mindre typer när ABI:t tillåter det
- Skicka index i stället för fullständiga structs när datan redan finns on-chain
Kortslutande villkor
De logiska operatorerna && och || kortsluter: det andra operandet utvärderas bara vid behov. Ordna villkoren så att den billigaste eller mest sannolikt avgörande kontrollen kommer först.
// Check the cheap flag before the expensive storage read
if (isEnabled && expensiveStorageCheck()) {
// ...
}Undvik överflödiga läsningar
Om ni läser samma calldata- eller minneselement flera gånger i loopens kodblock bör ni cacha det i en lokal variabel. Även om åtkomst till calldata är billigare än åtkomst till lagring ackumuleras kostnaden vid upprepade läsningar.
for (uint256 i = 0; i < len; ++i) {
uint256 v = data[i]; // read once
total += v;
if (v > max) max = v;
}Begränsa looparna
Obegränsade loopar över användarkontrollerade arrayer kan överskrida blockets gasgräns och göra funktionen permanent oanropbar, vilket innebär en risk för denial of service.
Begränsa alltid antalet iterationer eller använd ett pull-baserat mönster där användarna behandlar sina egna poster, så att varje transaktion håller sig inom säkra gasgränser.
require(ids.length <= 100, "too many");
for (uint256 i = 0; i < ids.length; ++i) { }Sätt ihop delarna
En optimerad loop brukar cacha längden, ackumulera i lokala variabler, använda indata i calldata, inkrementera med unchecked { ++i; } och vara begränsad.
Varje teknik ger en liten besparing var för sig, men tillsammans kan de minska loopens gasförbrukning avsevärt.
function batch(uint256[] calldata vals) external {
uint256 len = vals.length;
uint256 total;
for (uint256 i = 0; i < len;) {
total += vals[i];
unchecked { ++i; }
}
sum = total;
}Snabb kontroll
Varför är det billigare att använda calldata i stället för memory för en extern funktions arrayparameter?
Sammanfattning
Ni har lärt er gasoptimeringstekniker för loopar och calldata:
- Cacha arrayens längd innan loopen
- Ackumulera i lokala variabler och skriv till lagring en gång
- Använd
unchecked { ++i; }för säkra räknare - Föredra parametrar i
calldataoch minska nyttolaster - Begränsa alltid loopar för att undvika DoS på grund av gasgränsen
Därefter mäter vi dessa förbättringar med profileringsverktyg.
Lär dig Grunderna i Web3- och DApp-utveckling med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 29
- Lektioner
- 105
Vanliga frågor
Är lektionen ”Loop- och calldata-trick” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Grunderna i Web3- och DApp-utveckling, inklusive ”Loop- och calldata-trick”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Grunderna i Web3- och DApp-utveckling innehåller totalt 4 lektioner.
Vad lär jag mig i ”Loop- och calldata-trick”?
Billigare operationer Ni övar på Grunderna i Web3- och DApp-utveckling med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Grunderna i Web3- och DApp-utveckling?
Du behöver inga förkunskaper. Utbildningen i Grunderna i Web3- och DApp-utveckling på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Loop- och calldata-trick”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Grunderna i Web3- och DApp-utveckling-lektionen?
Ja. Varje Grunderna i Web3- och DApp-utveckling-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Modell för gaskostnader
- Lagringsoptimering
- Loop- och calldata-trick
- Mäta gas