diff --git a/docs/learn/encyclopedia/contract-development/rust-dialect.mdx b/docs/learn/encyclopedia/contract-development/rust-dialect.mdx index 5e51b7e6f..de714f8ae 100644 --- a/docs/learn/encyclopedia/contract-development/rust-dialect.mdx +++ b/docs/learn/encyclopedia/contract-development/rust-dialect.mdx @@ -43,7 +43,7 @@ The host object and host function repertoire has been designed to relieve the gu Using host objects instead of data structures in guest memory carries numerous benefits: much higher performance, much smaller code size, interoperability between contracts, shared host support for serialization, debugging and data structure introspection. -The guest does, however, has a small linear memory available to it in cases where dynamic memory allocation is necessary. Using this memory carries costs: the guest must include in its code a full copy of a memory allocator, and must pay the runtime cost of executing the allocator's code inside the VM. +The guest does, however, have a small linear memory available to it in cases where dynamic memory allocation is necessary. Using this memory carries costs: the guest must include in its code a full copy of a memory allocator, and must pay the runtime cost of executing the allocator's code inside the VM. This restriction is due to the limited ability of Wasm to support code-sharing: there is no standard way for the Wasm sandbox to provide shared "standard library" code within a guest, such as a memory allocator, nor does the host have adequate insight into the contents of the guest's memory to provide an allocator itself. Every contract that wishes to use dynamic allocation must therefore carry its own copy of an allocator. @@ -73,4 +73,11 @@ This is not a hard restriction enforced by the host, but a soft configuration ma Host objects have significantly different semantics than typical Rust data structures, especially those implementing _collections_ such as maps and vectors. -In particular: host objects are **immutable**, and often **share substructure**. They therefore resemble the data structures from pure-functional programming more closely than the typical imperative model used in many Rust programs. +In particular: host objects are **immutable**, and any "modification" to a host object returns a **full new copy** of the object, leaving the initial one unchanged. +For the most part this distinction is hidden through wrappers in the SDK, such that objects like `Map` or `Vec` appear to the contract programmer to be uniquely owned mutable values similar to Rust's standard library types, +but the underlying host objects are immutable, so have different performance characteristics. Specifically: cloning such an object is O(1), whereas any modification is O(N). +Since most host objects are typically very small, the O(N) cost of modification is typically cheaper than any alternative implementation involving shared substructures. + +**Note**: these container types `Vec` and `Map` should _not_ be used for managing large or unbounded collections of data. +For such cases, contracts should store data in multiple separate ledger entries, each with its own unique contract-defined key. +Doing so also limits the IO cost of a contract to only the entries it accesses, and furthermore allows concurrent modification of entries with separate keys from separate transactions. \ No newline at end of file