I have a struct with the following variables:
struct contract {
address customer;
uint8 tokentype; // 5 token types
uint8 size; // 5 sizes
bool gender; // 2 types
bool active; // 2 types
}
I'm not a computer scientist, but I think bools are 2 bits, and when I have 5 cases, I suppose that's 5 bits.
To save on gas and memory, I could store them as a uint instead of separate variables, so that each digit slot would reflect one item: {tokentype, size, gender, active} --> {digit4, digit3, digit2, digit1}. Thus 4411, would be the largest possible number for my set of cases, while 0 the smallest. I would then access them via pulling out some particular contract "con", so that I could apply logic on the cases using
for size, it's digit 3, and thus
con.digit3 / 1e3 % 10 = case of digit 3
which I could use in my contract via the generalized function, for various x and j:
if ((con.digitx / 1ex) % 10 == j)
I would replace values the following way. For example, if the existing value of digit3 is not 4, and I wanted it to be 4, I would apply the function
con.digit4 = con.digit4 + 4e3 - ((con.digit4 / 1e3) % 10) * 1e4;
In the context of Solidity's gas considerations, is there a more efficient way? I figure there is using a shift operation.
bools are 2 bits
- no, each one of them is 8 bits (so 16 altogether). You can optimize them into 2 bits by using a single uint and packing several flags into it, but it might ultimately "de-optimize" the gas-cost of your function or functions (and more generally, reducing "memory size" on the blockchain is not necessarily an optimization).more efficient way
is to use as much "memory space" as needed, and perform as little number of operations as possible. Your attempt to use less memory ultimately increases the number of operations and subsequently the gas-cost.