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

investigate ways to avoid heap allocations #16

Open
mcginty opened this issue Jun 21, 2018 · 8 comments
Open

investigate ways to avoid heap allocations #16

mcginty opened this issue Jun 21, 2018 · 8 comments

Comments

@mcginty
Copy link
Owner

mcginty commented Jun 21, 2018

Right now for the sake of cleaner syntax, there's allocation being done using Box structs to avoid forcing users of snow to specify a ton of ugly generics when they store sessions in their own structs, for example.

@mcginty mcginty changed the title investigate ways to avoid allocations investigate ways to avoid heap allocations Jun 29, 2018
@vks
Copy link

vks commented Jul 18, 2018

It would be an option to use impl Trait. Unfortunately, this does not allow users to store the results in their own structs.

Maybe associated types would help?

@mcginty
Copy link
Owner Author

mcginty commented Jul 19, 2018

@vks I think we'd need impl Trait to extend support for being used in structs, which it currently can't do and I'm not sure what the roadmap is for that.

If you have any suggestions for associated types I'm all ears! Another thought I had was to simply disallow external resolvers and use enums to avoid allocations, but of course that comes as a compromise.

@mcginty
Copy link
Owner Author

mcginty commented Sep 1, 2019

related to #62

@isislovecruft
Copy link

Why is snow doing Box<dyn SomeTrait> everywhere rather than &'a SomeTrait? Is it because the explicit lifetimes would make it harder for snow users?

@mcginty
Copy link
Owner Author

mcginty commented Oct 3, 2019

@isislovecruft yep, it's purely for ergonomic reasons. I'd love to use something like associated traits and maybe a convenience macro to be able to drop the Boxes while keeping roughly the same level of simplicity.

@tarcieri
Copy link
Contributor

tarcieri commented Oct 23, 2019

If you want trait objects without heap allocations, one option is an enum with Deref impl whose Target is the desired trait object. Something like this:

enum CipherBackends {
    #[cfg(feature = "backend1")]
    ....
}
impl core::ops::Deref for CipherBackends {
    type Target = dyn Cipher;

    fn deref(&self) -> &(dyn Cipher + 'static) {
        match self {
            #[cfg(feature = "backend1")]
            ....
        }
    }
}

This should work more or less the same as Box<Cipher>, but avoids keeping data on the heap.

Note that this does have the advantage that the size of CipherBackends will always be as big as the largest of the variants, but hopefully they're roughly the same size.

@mcginty
Copy link
Owner Author

mcginty commented Nov 10, 2019

@tarcieri the reason I didn't choose this method in the original design is because I wanted the option for people to implement their own crypto backends if snow didn't provide any that fit their needs. If it's totally clear that flexibility isn't necessary, we could definitely switch to something like this.

@tarcieri
Copy link
Contributor

Unfortunately I think you need either Box or a generic type parameter in that case, the former requiring a heap allocation, and the latter defeating the point of using an enum since it can just monomorphize rather than using a trait object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants