# Loop Optimisation for gas usage

``````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;
}
}
``````

I've been trying to see if there's any way to optimise this loop so that it consumes less gas, as it is executed a very large number of times in my contract, however, I can think of any obvious optimisations. Am I missing something?

UPDATE

``````  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;
}
}
``````

So I added the following code, however now `result` is always 0. I'm not sure what I'm doing wrong...Please note my_int and my_second_int are both `uint256` and `id` is an address

• Can you show us the context? eg from that we can't see what's in memory and what's in storage, or whether any matching entry in that array would do or whether you need the first one you come to. – Edmund Edgar Nov 18 '17 at 21:32

## 1 Answer

You could start by using a `uint` type for the loop variable rather than `uint8`. This is not obvious, but the compiler introduces extra code to do type-coercion when you use types smaller than 256-bits. This uses extra gas.

The main overhead cost will be the array bounds checking for `my_array[i]` which the compiler inserts whether you like it or not. Currently the only way to avoid that is to use inline assembly.

• could you please have a look at the edit? – mankee Nov 19 '17 at 0:13
• It's a bit hard to debug without the whole code. But some observations: (1) Memory calculation for `mload` should be in bytes, not bits; (2) Inside the `if` block, your comment says `add 512`, but you actually add `544`, and it probably ought to be `96 = 0x60` in bytes anyway; (3) you don't need to use assembly inside the `if` block really since it is executed only once (unless there is another outer loop you are not showing us). – benjaminion Nov 19 '17 at 5:52