Gas optimizations
Throughout the protocol are instances where more gas-optimized code would be beneficial.
For example, function calls are the most expensive instruction, requiring 1500 gas units.
In the function create
in dex::instrument
, the following call is made:
let base_decimals = coin::decimals<Base>();
let quote_decimals = coin::decimals<Quote>();
However, later, the return value of this function duplicates this call function again when it could use the previously retrieved values above.
Instrument<Base, Quote> {
owner,
price_decimals,
size_decimals,
min_size_amount,
base_decimals: coin::decimals<Base>(),
quote_decimals: coin::decimals<Quote>()
}
In-depth gas cost operations are noted here↗ and here↗.
Another such instance is the following code,
public fun is_full<V: store + drop>(queue: &Queue<V>): bool {
size(queue) == U64_MAX
}
public fun size<V: store + drop>(queue: &Queue<V>): u64 {
vector::length(&queue.nodes) - vector::length(&queue.free_indices)
}
which checks if the size of the queue is 2^64, an impractical scenario to occur.
Another point to consider from a gas-usage standpoint is the size of the splay trees. For example, in can_ask_be_matched
and can_bid_be_matched
, as the splay tree gets larger, placing orders become more expensive. Laminar mitigates this by splaying order queues.