-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove getCatalog because it is horrible for performance #135
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way we can not remove getCatalog and still gain these performance benefits? Many scripts and other services are using this.
Please ignore the prior approval, that was an accidental click, and I can't figure out how to undo it :P |
@@ -160,14 +160,22 @@ pub contract NFTCatalog { | |||
} | |||
} | |||
|
|||
pub fun getCatalog() : {String : NFTCatalogMetadata} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At best, I think we can add the new functions and put a comment above this saying not to use it.
No, not really.
If iteration over the catalog is really needed for certain use cases, paging should be added, so that iteration can be done in batches. However that is easier said then done, because iterating over a dictionary with |
You can page catalog with slice actually. Adding item to catalog is a rare event. Order is deterministic until dictionary is modified. we can use a lastmodified variable on catalog. Maybe pass it as a parameter etc. poor man’s cursor :) |
@bluesign is that how it works? Is that documented somewhere i couldn't find anything. maybe that is how it works currently and there were no guarantees given for that... It would be great if there were some dictionary hash or something that you could pass while paging and if it changed, you would know the dictionary keys have changed. |
@janezpodhostnik yeah it is implementation detail ( atree ) , but considering deterministic output, I don't think the order can change on cadence side per execution ( unless storage changes / dictionary modified ) I suggested before object hash also, but it didn't go too far. ( it would be very nice to have a hash property for resources and structs ) It would be very nice usage to check what changed in the account with storage browsing also. Unfortunately we will end up not usable state if we don't implement those primitives. ( paging, lazy arrays/dics etc) People will hammer ANs, ANs will put harsher limits to execution, nothing useful will be done via scripts. We already had this with events blocks range. |
every-time
getCatalog
is called this fetches the entire catalog from storage and copies it. This is terrible, especially since the catalog is growing.If a specific element is needed just use the existing
getCatalogEntry
or the newly addedmustGetCatalogEntry
which just has the pre-check that was duplicated everywhere in one place.Iteration over the entire catalog should only be used if really needed. In that case I added
forEachCatalogKey
method.Be aware that there are examples and scripts that recommend just iterating one
catalog.keys.slice
(or equivalent). This is not a good recommendation!catalog.keys
are not deterministically sorted! using this for paging will lead to bugs. A different mechanism should be put in place for paging.Another performance change that I added to this is the switch from
getNFTViewsFromCap
togetNFTViewsFromIDs
in cadence/scripts/get_nft_and_views_in_account.cdc. Because only views for a specific ID are needed, so no need getting all of them.missing from the draft: