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

Enhancement: Improving memory efficiency by eliminating the vtable in the managed class. #876

Closed
wants to merge 1 commit into from

Conversation

RealTimeChris
Copy link
Member

By making the destructor protected - we can remove the possibility that someone tries to delete one of the derived classes by deleting an instance of the managed class, which should allow for not having a virtual destructor.

Code change checklist

  • I have ensured that all methods and functions are fully documented using doxygen style comments
  • My code follows the coding style guide.
  • I tested that my change works before raising the PR.
  • I have ensured that I did not break any existing API calls.
  • I have not built my pull request using AI, a static analysis tool or similar without any human oversight.

@netlify
Copy link

netlify bot commented Sep 22, 2023

Deploy Preview for dpp-dev ready!

Name Link
🔨 Latest commit ac8ff40
🔍 Latest deploy log https://app.netlify.com/sites/dpp-dev/deploys/650dfce8ffe9460008a62824
😎 Deploy Preview https://deploy-preview-876--dpp-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@braindigitalis
Copy link
Contributor

why are you so obsessed with getting rid of the vtable here?
I already said it's over engineered and hard to read... theres no need to go this far to save 8 bytes.

@RealTimeChris
Copy link
Member Author

why are you so obsessed with getting rid of the vtable here? I already said it's over engineered and hard to read... theres no need to go this far to save 8 bytes.

Because I tend to fixate on things periodically - and I disagree that it's over engineered and hard to read - I've barely changed anything. Is it slightly more complex? Yes. Is it worth the memory savings? I would say it is - though I suppose that's what is up for debate here. The final say is ultimately yours though.

include/dpp/cache.h Outdated Show resolved Hide resolved
src/unittest/test.cpp Show resolved Hide resolved
include/dpp/cache.h Outdated Show resolved Hide resolved
include/dpp/managed.h Show resolved Hide resolved
deletion_queue = {};
}
}
if constexpr (std::is_same_v<emoji, value_type>) {
Copy link
Member

Choose a reason for hiding this comment

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

Why this btw, and making this function a template? Can't this function rehash every cache like how it was before?

Copy link
Member Author

@RealTimeChris RealTimeChris Sep 22, 2023

Choose a reason for hiding this comment

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

So we can static cast the managed pointers to their derived types and avoid falling into not being able to delete them, given that we've made the managed destructor protected. And we're doing the if-else here to avoid rehashing each of the caches unnecessarily, given that we now have to do this here:

dpp::garbage_collection<emoji>();
dpp::garbage_collection<role>();
dpp::garbage_collection<channel>();
dpp::garbage_collection<guild>();
dpp::garbage_collection<user>();
.

Copy link
Member

@Mishura4 Mishura4 Sep 22, 2023

Choose a reason for hiding this comment

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

But for example dpp::get_emoji_cache() returns a dpp::cache<emoji> *, right? So when doing dpp::get_emoji_cache()->rehash(); like how it was before, that would already call the function with the correct type, as dpp::cache<emoji>::rehash uses emoji anyways (see https://github.com/brainboxdotcc/DPP/blob/master/include/dpp/cache.h#L233)

Copy link
Member Author

Choose a reason for hiding this comment

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

Right but when we call garbage_collection repeatedly - one for each of the types, we don't want to rehash it for each of the calls.

Copy link
Member

Choose a reason for hiding this comment

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

Well you wouldn't need to call garbage_collection multiple times, just one like how it was before

Copy link
Member Author

Choose a reason for hiding this comment

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

No because we need access to the derived type to static_cast the managed pointer into, as seen here:

delete static_cast<value_type*>(g->first);

Copy link
Member

Choose a reason for hiding this comment

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

I see. Another thing however, how are we certain deletion_queue only contains objects of that type? The way i see it in

deletion_queue[object] = time(nullptr);
, any cache can add to it

Copy link
Member Author

Choose a reason for hiding this comment

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

There I've solved the "cache of any types" issue. It might be too over engineered, let me know what you think.

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Sep 22, 2023
…class.

By making the destructor protected - we can remove the possibility that someone tries to delete one of the derived classes by deleting an instance of the managed class, which should allow for not having a virtual destructor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants