for (uint8 i = 0; i < total; i++) {
if (myarray[i].my_int >= maximum && my_array[i].my_second_int <= maximum) {
result = my_array[i].id;
break;
}
}
Ich habe versucht zu sehen, ob es eine Möglichkeit gibt, diese Schleife so zu optimieren, dass sie weniger Gas verbraucht, da sie in meinem Vertrag sehr oft ausgeführt wird, aber mir fallen offensichtliche Optimierungen ein. Übersehe ich etwas?
AKTUALISIEREN
for (uint8 i = 0; i < total; i++) {
assembly {
//We only add 32 bits because my_int is first in the struct.
my_int := mload(add(add(myarray_slot, 0x20), mul(i, 0x2A0)))
//We add 288 because my_second)int is second in array
my_second_int := mload(add(add(myarray_slot, 0x120), mul(i, 0x2A0)))
}
if (my_int >= maximum && my_second_int <= maximum) {
assembly {
//We add 512 to get to address position in struct (2 * 256 bit ints) and we multiply with 672 (total size of struct (2 ints * 256 + address of size 160 bits))
result := mload(add(add(myarray_slot, 0x220), mul(i, 0x2A0)))
}
break;
}
}
Also habe ich den folgenden Code hinzugefügt, der jetzt jedoch result
immer 0 ist. Ich bin mir nicht sicher, was ich falsch mache ... Bitte beachten Sie, dass my_int und my_second_int beide uint256
eine id
Adresse sind
Sie könnten damit beginnen, einen uint
Typ für die Schleifenvariable anstelle von zu verwenden uint8
. Dies ist nicht offensichtlich, aber der Compiler führt zusätzlichen Code ein, um eine Typumwandlung durchzuführen, wenn Sie Typen verwenden, die kleiner als 256 Bit sind. Dies verbraucht zusätzliches Gas.
Die Hauptkosten für den Overhead sind die Überprüfung der Array-Grenzen, für my_array[i]
die der Compiler einfügt, ob es Ihnen gefällt oder nicht. Derzeit besteht die einzige Möglichkeit, dies zu vermeiden, darin, die Inline-Assemblierung zu verwenden .
mload
sollte in Bytes erfolgen, nicht in Bits; (2) Innerhalb des if
Blocks sagt Ihr Kommentar add 512
, aber Sie fügen tatsächlich hinzu 544
, und es sollte wahrscheinlich sowieso in Bytes sein 96 = 0x60
; (3) Sie müssen die Assemblierung nicht wirklich innerhalb des Blocks verwenden, if
da sie nur einmal ausgeführt wird (es sei denn, es gibt eine andere äußere Schleife, die Sie uns nicht zeigen).
Edmund Edgar