Comments (4)
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.
- A streaming API to iterate the bytes in a virtual buffer that spans multiple real buffers.
- 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.
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.
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.
Fixed by #103
from haywire.
Related Issues (20)
- Default configuration
- haywire_hello_world sometimes segfaults HOT 4
- build fails on OS X 10.11.3 with latest Xcode HOT 2
- [Discussion] Running the benchmarks
- Reduce malloc() and free() calls HOT 2
- Error building on Windows 2012 R2 Standard (x64) and MVSC2015 HOT 1
- Errors building ib Ubuntu HOT 1
- How about haywire vs h2o or mongoose? HOT 1
- remote peer address
- i run hello world sample on windows(visual studio), when i change thread count > 0, sample can't run HOT 1
- compiling with gyp HOT 3
- Is there any plan to support websocket?
- Should the print body function (hw_print_body) be in Hawyire.h?
- Assertion failed: (server->loop == client->loop) when starting IPC worker threads
- Create a Makefile to replace make.sh HOT 1
- Investigate using mlock
- Split the multi-event loop IPC and REUSEPORT multi-threading from http_server
- Assertion failed: ... does not yet support other types of streams
- pointer being freed was not allocated
- Use the fastest Http Parser picoparser
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from haywire.