Schleifenoptimierung für den Gasverbrauch

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 resultimmer 0 ist. Ich bin mir nicht sicher, was ich falsch mache ... Bitte beachten Sie, dass my_int und my_second_int beide uint256eine idAdresse sind

Können Sie uns den Kontext zeigen? zB können wir daraus nicht erkennen, was sich im Arbeitsspeicher und was im Speicher befindet, oder ob ein passender Eintrag in diesem Array ausreichen würde oder ob Sie den ersten brauchen, zu dem Sie kommen.

Antworten (1)

Sie könnten damit beginnen, einen uintTyp 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 .

könntest du bitte mal in die editierung schauen?
Es ist ein bisschen schwierig, ohne den gesamten Code zu debuggen. Aber einige Beobachtungen: (1) Die Speicherberechnung für mloadsollte in Bytes erfolgen, nicht in Bits; (2) Innerhalb des ifBlocks 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, ifda sie nur einmal ausgeführt wird (es sei denn, es gibt eine andere äußere Schleife, die Sie uns nicht zeigen).