core-contracts icon indicating copy to clipboard operation
core-contracts copied to clipboard

An optimizable point when operating nesting near-sdk::Collections

Open marco-sundsk opened this issue 3 years ago • 0 comments

description

There is a common use pattern of near-sdk::Collections, like this:
example code from: https://github.com/near/core-contracts/blob/nft-simple/nft-simple/src/lib.rs

pub tokens_per_owner: LookupMap<AccountId, UnorderedSet<TokenId>>,

and corresponding operation code like this:
example code from: https://github.com/near/core-contracts/blob/nft-simple/nft-simple/src/internal.rs#75

pub(crate) fn internal_add_token_to_owner(
        &mut self,
        account_id: &AccountId,
        token_id: &TokenId,
    ) {
        let mut tokens_set = self
            .tokens_per_owner
            .get(account_id)
            .unwrap_or_else(|| UnorderedSet::new(unique_prefix(account_id)));
        tokens_set.insert(token_id);
        self.tokens_per_owner.insert(account_id, &tokens_set);
    }

We can see that, when we changed (modify/add/remove) the item of inner collection (UnorderedSet here), we still take two insert actions. One is to insert inner collection to reflect our goal, the other is to insert this inner collection back to outer collection.

Problem

Let's take the new and clear action of inner collection out of the table (cause they are rare to happen in common case, and can be handled seperately).
From the aspect of storage, we can easily tell that the second insert action is meaningless. Cause the inner collection itself, as a value of outer collection, is untouched.
Will this meanless insert action cause some unnecessary gas cost? After all, the read/write action of storage is one of main parts of gas consumption.

Possible solution

Is there any other code pattern we can use to directly operate the inner collection and leave the outer one untouched?

marco-sundsk avatar Apr 07 '21 02:04 marco-sundsk