0

My rust is limited, I would like to simplify some of my code, and it would be helpful if I could have a caching function to cache database reads in memory.

Are there any helpers that I can use for this? Can you please give me some advice on how I can do this?

For example:

fn get_from_cache_or_read() -> MyStorageItem {
   // Some logic here that would check if a cache item exist
   // Or make a call to the database

   MyStorage::<T>::get()
}

4
  • Could you elaborate more? Why do you want a cache? What does it use for? Jan 6, 2023 at 3:24
  • 1
    Any storage reads while executing an extrinsic will be cached so if you happen to read the same thing twice in the same transaction then the weight would only be for reading it once.
    – Squirrel
    Jan 6, 2023 at 8:49
  • Even if this is one read, we are still reading from the overlay. I asked a similar question, and it was recommended to use the in-memory cache still: substrate.stackexchange.com/questions/2574/…
    – Yatusabes
    Jan 6, 2023 at 20:16
  • 1
    The overlay is about as performant as caching can get. Of course, when you write code, if you DO NOT use a cache, then it will be fastest. This is what I recommended by reusing an initialized variable, but this is not always possible or convenient. The overlay is in-memory already, so I think you just have a misunderstanding here.
    – Shawn Tabrizi
    Jan 7, 2023 at 1:35

1 Answer 1

2

Reads are already cached. Calling MyStorage::<T>::get() twice will only incur one DB read.

The first time you call get()/set() it will each count as DB operation. All following ones of the same kind will be DB free, since they are tracked in the transactional overlay. This must be so since a TX can revert in which case it will not be persisted to DB.
Even better: if you call set(); get(), the get() is free and never hits DB. Not so much if you do get(); set() obviously.

Example bench and weight.

3
  • So during weight estimation, one should forgo counting redundant get() calls to storage items? I ask it explicitly because one would not do the same with set() calls as writing to DB is a unique operation every time unlike a read. Jan 6, 2023 at 12:53
  • I think benchmarking already has this caching into account. Jan 6, 2023 at 12:58
  • I updated the answer. Jan 6, 2023 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.