Question about performance, mutability and computation

performance and cycle burning wise, would it matter much if you use structs to fetch and / or mutate data compared to having all the fields in separate memory allocations and combining them on-request?

The dapp i’m working on required occasional changes to the “base entity (which is a struct at this moment)” but i don’t like making every field that i add optional.

I personally think it would require more calculations for retrieving data but less for mutating data?

Struct

struct Data {
   name: String;
   description: String;
   ...
}

pub static DATASETS: RefCell<StableBTreeMap<ID, Data, Memory>>;

fn get_entity(id: ID) -> Entity {
    let data = DATASETS.with(....);
    return data;

Seperate fields

pub static NAME: RefCell<StableBTreeMap<ID, String Memory>>;
pub static DESCRIPTION: RefCell<StableBTreeMap<ID, String Memory>>;
...

fn get_entity(id: ID) -> Entity {
    let name = NAME.with(....);
    let description = DESCRIPTION.with(....);

   let entity = Entity {
        name,
        description
   };
   return entity;
}
1 Like

If you are using name and description frequently together, I’d expect the former solution with structs to be better in terms of locality.

The second solution should require about twice as many memory accesses than the first one, as double the memory pages would likely have to be fetched from memory.

I also think it makes more sense from a readability point of view.

1 Like

And to answer the question more broadly, you can use the performance_counter API, which when called will tell you how many instructions were executed from the beginning of the call to that point, so you can easily compare both approaches in your canister and see which one performs best.

1 Like

Thanks for the responses, will check it out. What would be the go-to solution you recommend when handling changing base entities?