-
-
Notifications
You must be signed in to change notification settings - Fork 11
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
Add alteration methods to IArray #34
Open
ColonelThirtyTwo
wants to merge
1
commit into
yewstack:main
Choose a base branch
from
ColonelThirtyTwo:array-edit
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I guess our main complaint in accordance with #17 is this
.collect()
here allocates a whole new array.When iterating over items, sure, they can be cloned, since each item iteration makes a clone (
ImplicitClone
that is, meaning not even allocating anything besides on the stack, just doing things like incrementing anRc
count, for example) and then throws that clone out once its done.Allocating a new array (also, WASM (since its a yew-stack crate) performance for such allocations I'm not sure about) means looking for a lot of space (both of the arrays combined could be massive - literally, in my native language word "array" translates to "massive"), and then moving all of the made clones into it. This means adding a new single item would require making a whole array clone of a worst-case size. Imagine adding two in a row?
Sure, the user could make some kind of temporary storage to insert all of new items at once, but the API cannot prove that user would not call
push
for adding single items in a big loop instead. Colloquially in IT and other areas of engineering this is called making the design "idiot-proof".Vec
does actually amortize this kind of cost with separatingsize
andcapacity
. Most of optimizations we could work on (talked over in #17) would probably lead us to just an inferiorVec
/Rc<Vec>
.I believe its better to make the user do an intentional
to_vec
(I wonder if its possible to optimize into ainto_vec(self)
likemake_mut
so it just copies bytes (moves?) into newly allocatedVec
in case there is only oneRc
?) or newly addedmake_mut
for just mutating some items, orget_mut
(I already commented that, I'll be waiting for that to be added / explained why it could not be added).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.
The only way
Rc<[T]> -> Vec<T>
could be more efficient than moving out of theRc<[T]>
buffer would be ifVec<T>
reused the storage ofRc<[T]>
, but it can't - the Rc buffer would be prefixed by the refcount, which Vec won't know about and won't deallocate correctly. You can't even move values out of anRc<[T]>
becausetry_unwrap
andinto_inner
need[T]: Sized
. So copying is really the only way.to_vec
-> edit ->collect::<Rc<[T]>>
would involve two copies, which isn't great. Using iterators over the original slice would be better but gets complex.IMO the simple insert/remove methods are convenient for the usual UI things of adding/removing a single element, though I agree they are kinda footguns for more involved usage.
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.
The thought is that we don't necessarily
clone
each item into the newVec
, but move them instead. In most cases, a move is just like a copy, if not precisely that (but doing it manually would requireunsafe
and working withPin
I guess (also, do we need to handlePin<IArray/IString/etc>
somehow?)).I guess this is our limiting factor. Probably making a tracking issue on this repo that would ask to add to Rust
into_vec
or something of the sort to theRc<[...]>
, unless usingunsafe
in this repo is a non-issue.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.
Even with unsafe, you'd have to somehow be able to free the underlying
Rc
allocation without dropping the items, and unlike with Vec, there's no guarantees on the allocation that Rc makes, since there's a refcount on it as well. Rust would need to add something likeRc::drain
.EDIT: now that I think about it, you may be able to do it by transmuting to
Rc<[MaybeUninit<T>]>
, moving the values out, then dropping the transmuted Rc, which will free the memory without running destructors. Assuming that's the only reference, of course.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.
I wouldn't mind that this go in a separate PR so we can merge this one already.