❔ Best way to cache index of an object in a list
I have a list with anywhere from 0 to maybe 1000 objects in it, and I have to try and find the index of that object very quickly (during mouse move events, so 100s of times per second possibly)
What would be a good way to optimise this?
38 Replies
I tried storing the index of the object in the object itself, but because the objects can move in that list during said mouse events, I don't think it would be that much faster, because if I move an object to the start of the list for example, I have to increment the index of every object between the object's previous index and 1
Kinda considering doing something like calculating the size of the object, and getting the address of the current instance and trying to calculate it based on that address and the object size
Show some code.
It's impossible to give you an answer without context of the surrounding code.
It's for a video editor, the list being a list of clips within a track
Post the relevant code snippet to Pastebin and send us the link here so we can see what's being done.
I don't know what part to send, it's kinda just all over the place
Can you show the whole thing?
Like, where are you updating the list?
And how are you doing it? (In code.)
I add a clip to the list whenever a clip is added to a track... obviously, and that could be called from either dragging a thing into the timeline, copy+paste, etc.
At the moment it's completely unordered, but i'm trying to see if I can sort it by the timestamp of the clips which might help
Is the insertion order relevant?
O log n i think
It's not
Like, if I add two tracks at different times, does it matter if they're in the correct chronological positions?
Also, can there be the same track twice on this list?
Tracks can be in any order, depending on how they're added in the UI, and no there can't be duplicate tracks
Nor duplicate clips
Would it be easier if you could see the github code?
This code base is cheeks so you'd have to work around it
Yes, that would help.
It seems to me you don't really need to know the index of a given element of the list. Instead you wish to only know whether that element in present in the list, is that right?
Because it's an MVVM app, sometimes I have to map the model (Clip) to a view-model (ClipViewModel), and so it would help with performance if I could directly index into either model or view-model track lists
Do you have an example of that happening?
Not in the git repo... I have yet to push it but here:
Wait that doesn't help much
Still I see no usage of the index.
It was in the GetSelectedClipsAtFrame method
Still seems like you're not using any indexes here.
You're just iterating the list.
Just trying to find an example, i can barely get myself around this project
I don't use this method apparently but
which is them implemented as
Are you sure this
GetClipByModel
compiles?Yeah
Is there an implicit conversion between
Clip
and ClipViewModel
?Nah
GetClipByModel
is defined in TrackViewModel
, where clips
stores ClipViewModel
sI see.
I tried to keep the standard of view models containing a
Model
property, being their model objectWell, to answer your question: the most appropriate data type here appears to be
HashSet<Clip>
instead of List<Clip>
, since it guarantees uniqueness of elements, ordering doesn't matter, and all read/write operations are O(1).
(That said, this whole project is overwhelmingly overengineered, and if I'm being honest performance is the absolute last thing you should be worrying about here.)
Here's an article on hash sets: https://medium.com/@shawnastaff/c-collection-types-hashset-vs-list-bae022e7b439.The clips do need to be ordered between the model and view model though, otherwise to map a Model to ViewModel, I'd have to search one of the lists (e.g. Track Model list) for the object's index to then map into the other list (e.g. ViewModel list)
So as long as those two lists are in sync, then the app works fine, and the actual clips themselves can be unordered
Overengineered though?
IIRC, the hash set implementation of c# maintains ordering of the elements inserted.
although this behavior is not documented
you should be fine using a hashset
The hash set doesn't contain an IndexOf function though right?
I can't seem to get binary sorting to work either 😦
you won't need one.
you don't need to know the index of anything.
you're not using it for anything, so you can just query the hashset.
I may do at some point though
If I need to map a Clip Model to a ViewModel, I have to find the index of the Clip Model in the Timeline Model, then use that to directly index into Timeline ViewModel
like the method I showed above. Even though I don't use it now, I may be using it at some point
Look up YAGNI on Google.
@carrotther Do they have to click and hold a mouse button down while dragging a clip around to position it? Why wouldn't you store a reference somewhere when they start a drag on the clip?
In a web app you might have a list on a timeline that you bind to, and the potential 'drop' locations for an item would just be visual and wouldn't change the cannonical order until the user releases the mouse...but it sounds like you might have some more complicated concerns? Previewing the drop in a more nuanced way?
I want to do this but I don't know how to do it in WPF so I'm stuck just moving the live clip around
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.