Skip to content
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

[3.x] Add readahead to VariantParser #65079

Merged
merged 1 commit into from
Dec 4, 2022

Conversation

lawnjelly
Copy link
Member

@lawnjelly lawnjelly commented Aug 30, 2022

Adds a readahead buffer to VariantParser, to prevent large numbers of freads for single bytes, which is inefficient.

Notes

  • Part of a few areas I'm aiming to improve as part of profiling during the MergeNode PR. VariantParser appears in a lot of places in Godot, and it turns out that it ultimately calls fread byte by byte (at least on linux), and this can be super slow, even with disk caching.
  • The VariantParser always seems to read in linear order, so isn't subject to some of the pitfalls of readahead (moving the filepointer around etc). This type of access also can be optimized in a way that freads cannot (the file could be changed between each individual fread, for instance).
  • There are alternative approaches to the same problem, such as putting the readahead into the file classes, but this could be counterproductive in some situations without knowing the access patterns. Another alternative is reading the whole file into RAM first, but this could use up a large amount of RAM without necessarily being significantly faster than a smaller readahead.
  • This gives about 30% speed increase to loading scenes (it varies according to the scene content), especially useful for large scenes. This is measured using scenes from WroughtFlesh and TPS demo, and SSD. Increase in performance may be higher using hard disk.

Measurements

For performance measurements I used a version where the new and old could be #ifdefed between the two, and added a timer around the load_scene() in EditorNode::open_request().

@lawnjelly lawnjelly requested a review from a team as a code owner August 30, 2022 11:02
@lawnjelly lawnjelly added this to the 3.6 milestone Aug 30, 2022
@lawnjelly lawnjelly force-pushed the faster_variant_parser branch 3 times, most recently from 4e461d4 to 72f4b2b Compare August 30, 2022 11:25
Copy link
Member

@timothyqiu timothyqiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me :) Left a few small nitpicks.

core/variant_parser.cpp Outdated Show resolved Hide resolved
eof = true;
return 0;
}
return get_char();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit surprised by the recursive call TBH 😛

Could be replaced by the following structure. But it's also fine to keep it the way it is.

if pointer >= filled:
    filled = _read_buffer()
    if filled == 0:
        pointer = 1
        eof = true
        return 0
    pointer = 0

return buffer[pointer++]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, same result.

One of the reasons I got into the habit of putting the expected result to be the if statement (rather than the else) is that long ago I read the assembly generated tends to favour that branch (much like the unlikely keyword, before that was available). Whether that is still the case I don't know, have to test in godbolt! 😀

Adds a readahead buffer to VariantParser, to prevent large numbers of freads for single bytes, which is inefficient.
Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reduz approved the 4.0 PR, so this one should be good too.

@akien-mga akien-mga merged commit 0cd3db4 into godotengine:3.x Dec 4, 2022
@akien-mga
Copy link
Member

Thanks!

@lawnjelly lawnjelly deleted the faster_variant_parser branch December 5, 2022 15:25
@akien-mga akien-mga changed the title Add readahead to VariantParser [3.x] Add readahead to VariantParser Sep 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants