I guess there is not much to get since not many operations are included and the operations are very fundamental (shift, assign). I created a solution that can save 28 gas per conversion though:
pragma solidity ^0.6.3;
contract Test {
function b32ToU24(bytes32 barray) external pure returns (uint24) {
return uint24(bytes3(barray << 24));
}
function b32ToU24ASM(bytes32 barray) external pure returns (uint24) {
uint24 result;
assembly {
// Right shift barray by 26 bytes, assign remaining 6 bytes to result
// Since result is an uint24, the 3 msB will not be regarded
result := shr(0xd0, barray)
}
return result;
}
}
Using the solc compiler 0.6.3 with optimizations, function b32ToU24 requires 258 gas whereas function b32ToU24ASM requires 230 gas. Without optimization 327 gas and 309 gas respectively. Depending on the context there might be more margin for optimizations.
Edit1: Since you have an array of bytes32 values, you have to adapt the solution in a way that iterates through the array and loads the data (using mload) before. If you want to store the values in an array of uint24 you can use mstore with an adequate offset. (assuming everything happens in memory)
uint24(bytes3(currentData << 24))
but cheaper? I doubt that there is one, but regardless of that, the rest of your code has nothing to do with the problem at hand, so I recommend that you get rid of it and leave only that one piece of code. It would make your question more focused on the actual problem, thus more inviting for others to read through and come up with alternative suggestions. – goodvibration Feb 17 '20 at 1:31