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

More memory efficient GerberCode trait #5

Closed
dbrgn opened this issue Nov 12, 2016 · 9 comments
Closed

More memory efficient GerberCode trait #5

dbrgn opened this issue Nov 12, 2016 · 9 comments

Comments

@dbrgn
Copy link
Owner

dbrgn commented Nov 12, 2016

Right now the GerberCode trait allocates lots and lots of strings because it returns the String type. We should change this to using a writer object, similar to the way Display does it.

I already wondered whether we should actually use the Display implementation instead of using our own trait, but I don't think that's a good idea.

@dbrgn
Copy link
Owner Author

dbrgn commented Mar 11, 2017

I thought about this a bit.

The best way would probably be a trait like this:

use std::fmt::Write;

trait GerberCode<W: Write> {
    fn to_code(&self, writer: &mut W) -> GerberResult;
}

It could be used like this:

impl<W: Write> GerberCode<W> for Comment {
    fn to_code(&self, writer: &mut W) -> GerberResult {
        writeln!(writer, "G04 {}*", self.text)
    }
}

Try it: https://is.gd/Gu910t

(Edit: Removed some long text that didn't really make sense after reading it again...)

What do you think, @rnestler @ubruhin?

@dbrgn
Copy link
Owner Author

dbrgn commented Mar 11, 2017

And @rnestler, just out of curiosity, do you know of a way to benchmark the before/after versions to see the impact (number of memory allocations) of this change?

@rnestler
Copy link

Using #[bench]?

@dbrgn
Copy link
Owner Author

dbrgn commented Mar 11, 2017

@rnestler That only measures speed, not allocations.

@ubruhin
Copy link
Contributor

ubruhin commented Mar 11, 2017

The best way would probably be a trait like this:

Looks good! This way it would be even possible to write directly into a file, without allocating a huge string for the whole file.

That only measures speed, not allocations.

Since allocations also require cpu time (which we want to keep low), measuring speed makes probably more sense than measuring the count of allocations, doesn't it?

@dbrgn
Copy link
Owner Author

dbrgn commented Mar 11, 2017

Looks good! This way it would be even possible to write directly into a file, without allocating a huge string for the whole file.

That's a good point! Yes. Or a BufWriter, which saves some I/O compared to raw files.

Since allocations also require cpu time (which we want to keep low), measuring speed makes probably more sense than measuring the count of allocations, doesn't it?

Yes, it was more about my curiosity on how this affects allocations :)

@rnestler
Copy link

Yes, it was more about my curiosity on how this affects allocations :)

To count the allocations you can use valgrind. But maybe you'll have to use the system allocator instead of jemalloc, see rust-lang/rust#28224.

@dbrgn
Copy link
Owner Author

dbrgn commented Mar 24, 2017

@rnestler any ideas about error handling? If an error occurs while writing to the writer, it might be left in an invalid state. Do we care about that? Would there be options for recovery?

@rnestler
Copy link

If an error occurs while writing to the writer, it might be left in an invalid state. Do we care about that?

I don't think it's that bad of a problem to have a partially written file if something bad happens during serialization. But we should avoid most logic errors by using the type system and fail early on the construction of these types.

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

No branches or pull requests

3 participants