-
-
Notifications
You must be signed in to change notification settings - Fork 21.9k
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
Reduce and prevent unnecessary random-access to List
#90705
Conversation
@@ -152,9 +152,10 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met | |||
|
|||
return_doc_from_retinfo(p_method, p_methodinfo.return_val); | |||
|
|||
for (int i = 0; i < p_methodinfo.arguments.size(); i++) { | |||
int i = 0; |
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.
These are to allow the use of the i
variable, and unfortunately c++17 doesn't allow initializing multiple variables of different types in the for
loop
Array arguments; | ||
for (int i = (has_return ? -1 : 0); i < mi.arguments.size(); i++) { | ||
PropertyInfo pinfo = i == -1 ? mi.return_val : mi.arguments[i]; | ||
if (has_return) { |
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.
Split this up because of the use of iterators
const PropertyInfo &prop = info.arguments[i]; | ||
if (!_is_exact_type(prop, p_arguments[i].type)) { | ||
int i = 0; | ||
for (List<PropertyInfo>::ConstIterator itr = info.arguments.begin(); itr != info.arguments.end(); ++itr, ++i) { |
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.
There's a few of these cases, seems a common paradigm.
I do wonder if using the for each
simpler version and putting the i++
on the first line might end up being easier to read. Maybe there's a more elegant way.
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.
Can look into them
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 did these, as seen above, to avoid any risky cases to ensure the iteration is clean, keeping the iteration in one place feels safer to me given some errors I accidentally caused with some of these cases when I used for each
syntax, so will keep these for now for a potential cleanup down the line to ensure they work correctly
Random-access access to `List` when iterating is `O(n^2)` (`O(n)` when accessing a single element) * Removed subscript operator, in favor of a more explicit `get` * Added conversion from `Iterator` to `ConstIterator` * Remade existing operations into other solutions when applicable
9a09918
to
955d5af
Compare
Overall this looks great. I'd be tempted to take the plunge and use local variables (e.g. reference) in a few cases where multiple These weren't there originally granted, so I understand being wary of introducing bugs via duplicate variable names or something. Or could be left to another PR. |
Fixed the unnecessary referencing in |
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.
Looks okay from looking through as best I could (quite long PR), although not tested.
I've tried to compare results between Either way, I've gotten this from hyperfine by running all its GDScript benchmarks:
This PR seems to provide a tiny overall speedup (in terms of overall runtime, including startup + shutdown) across an average of 10 runs for each. Standard deviation is still quite high so take it with a grain of salt, but at least we can be assured this change doesn't harm performance. |
It is good to confirm there is no slowdown. 👍 Existing common path performance sapping cases will (hopefully) mostly already have been fixed. The aim here is to make it more difficult to inadvertently introduce performance hotspots in the future, which then need extra work to identify and fix. There's a number of other data structures which tend to be more appropriate if elements are heavy, there is random insertions / deletions / moves, and indexed access is required, which is why indexed access to linked list is usually a bit of a "code smell". |
Thanks! |
Thank you! If you or anyone come across things related to this just point me that direction if any help is needed for adjusting to these changes |
Exactly, thank you I am going to add a few follow-up improvements, like replacements with |
This comment was marked as outdated.
This comment was marked as outdated.
Using Bur you likely shouldn't be using |
I'm passing data to |
I think editing the elements in this way isn't necessary, adding and removing from the end, or creating a new list might be better |
Random-access access to
List
when iterating isO(n^2)
(O(n)
when accessing a single element)get
Iterator
toConstIterator
Didn't (generally) replace uses of
List
with other structures except a few cases where it avoided a lot of code weirdness, it takes a lot more detailed evaluation of uses to handle that side, better left for other PRs by area maintainers