Slow query speeds, related to stable memory?

I have created a simple canister for a demo app – a companion app to the ic-siwe library. All works well but query calls are kind of slow. I know update calls can take two or more seconds but so does my query calls. Is that expected? I am using stable memory.

Try for instance the list_profiles() call.

Here are snippets with relevant code:

thread_local! {
    static MEMORY_MANAGER: RefCell<MemoryManager<DefaultMemoryImpl>> =
        RefCell::new(MemoryManager::init(DefaultMemoryImpl::default()));

    static USER_PROFILES: RefCell<StableBTreeMap<String, UserProfile, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(0))),
        )
    );
}

#[query]
fn list_profiles() -> Result<Vec<(String, UserProfile)>, String> {
    let profiles = USER_PROFILES.with(|p| p.borrow().iter().collect::<Vec<_>>());
    Ok(profiles)
}
1 Like

@ielashi knows best but, my understanding is indeed than stable memory is a bit slower than heap memory because every access requires deserializion respectively serializion - i.e. every read requires a deserialization and write a serialization of what’s in/out the memory.

That said, if the sample of data is small and entities are not gigantic, I don’t think it should make that a noticable difference.

Regarding your sample, I generally use range instead of iter but I can in your example it does not make much a difference.

Stupid question but, you are also sure that you deployed with query right?

2 Likes

I think that’s indeed the issue. The function seems not to be annotated as a query otherwise Candid UI should render a Query button instead of a call Call button if I’m not mistaken.

1 Like

:person_facepalming:

I moved a bit too fast and forgot marking the call as query in the did. Now the calls are much quicker. Thanks!

2 Likes

Been there, done that.

Cool to hear it works out!

1 Like