The first thing that needs to be understood is the existence of a Storage Overlay, which caches values which have been read or written to inside of a block. This means, if you read a storage item, the first time, it will need to navigate through the whole merkle trie, and fetch that storage item. But the second time, it just reads from the storage overlay, since that value has been cached by the client.
Now reading from this storage overlay is quite fast compared to reading from the database, but still will never be as fast as using an in-memory value, since reading from storage overlay.
So you should absolutely optimize this kind of behavior by using Clone
or Copy
where possible. For example:
This is bad:
// This is strictly less efficient.
let my_value = MyStorage::<T>::get();
let my_value_again = MyStorage::<T>::get();
This is good:
// This is strictly more efficient.
let my_value = MyStorage::<T>::get();
let my_value_again = my_value.clone();
Where such optimizations can happen, they should. Hopefully this is pretty obvious in retrospect.