If you use structs with integers smaller than the maximum available value, like int8, uint8, int32, uint32, you can have the chance that the solidity compiler optimizes the values into one storage element. Sometimes the storage is optimized even without an explicit struct, just with defining the small integers in a row. Taking the following code segment:
contract gasOptimisation{
uint8 a;
string test1;
uint8 b;
string test2;
uint8 c;
string test3;
uint8 d;
struct Integers{
uint8 a;
uint8 b;
uint8 c;
uint8 d;
}
Integers ints;
function setInt() {
a = 1;
b = 2;
c = 3;
d = 4;
}
function setStruct(){
ints = Integers(1,2,3,4);
}
}
Running setInt costs more than two times as much gas as running setStruct, because probably the compiler optimizes the four variables into one 32 byte word. However, if we remove the string declarations from the uint8 variables on the top of the contract, than setInt function and the storage of a,b,c,d variables are optimized as well, even without struct.