Giter VIP home page Giter VIP logo

Comments (4)

kellabyte avatar kellabyte commented on July 24, 2024

1. Abandon zero-copy optimizations

memcpy into expanding buffers.

2. Continue with zero-copy optimizations

Manage multiple buffers for a single request and retain pointer locations. This means a body (and potentially header?) could span multiple buffers. This means we can't expose pointers to user facing API's and we need to expose 2 types of API's.

  1. A streaming API to iterate the bytes in a virtual buffer that spans multiple real buffers.
  2. A memcpy API in case someone wants to do foo = request->get_body() as a whole value.

This allows us to retain zero-copy when people don't use certain headers or body values instead of memcpy'ing everything while still offering a memcpy when someone wants the full buffer.

Concerns

The big question: Does all this buffer management negate the performance optimization of zero-copy and would memcpy just end up being equal and simpler?

3. Realloc and resize the buffer

I like this option the most. It removes complicated buffer management and the problem of a header or body being split between buffers. That will make the internals much more complicated. Why not realloc() and increase the size of the original buffer when libuv requests more?

The main problem I see with this is we can't just give back the reallocated buffer to alloc_cb() because the pointer will be pointing to the beginning and the half parsed request will be overwritten. We need to realloc and adjust the pointer location to where it left off.

Performance implications

It won't affect requests that fit within 64KB much more than the current architecture. It'll only have a performance impact when it needs to resize with realloc() but otherwise the rest of the code works as it does currently.

I think this will work. Comments?

from haywire.

nmdguerreiro avatar nmdguerreiro commented on July 24, 2024

I'm in favour of implementing option 3), as that was what I was planning to try first after thinking about it a bit more.

I'm assuming that option 1) is the same as 3), except for the fact there would be an additional copy to generate null terminated strings and not to use hw_string.

Option 2) isn't very appealing IMHO. Even though we'd be saving CPU time in Haywire land, assuming the client wants all the data in one go (i.e. non-streaming) it would have to pay the CPU cost of iterating through the stream or allocating a big enough memory block and copying the data there. The end result would be that we would be doing memcpy in Haywire.

Going back to option 3), if we allocate 64KB by default and keep track of how much we've used and give the rest back to libuv during the alloc callback, we wouldn't need to realloc unless required.

One thing to keep in mind though, is that realloc may return a pointer to a different memory region, which means that any pointers to headers, query string, url, or even the beginning of the body would have to be reassigned by calculating the offset on the original buffer, adding that offset to the new buffer start and assigning the value to the new pointer. (I wonder how complicated this will be with pico parser, for now I'll focus on http_parser).

I'll have a go at this and see how far along I get.

from haywire.

kellabyte avatar kellabyte commented on July 24, 2024

Hmm interesting points. I don't have any experience using realloc(). Pointer locations changing could be a problem. Let me know what you find out. I like option 3 as well.

from haywire.

nmdguerreiro avatar nmdguerreiro commented on July 24, 2024

Fixed by #103

from haywire.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.