-
Notifications
You must be signed in to change notification settings - Fork 853
Switch to Span/Memory internally #1900
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
Comments
Note that for this to be worth it:
|
Some thoughts on this...
|
I just figured out that the lack of BCL support probably won't block us. Although it isn't possible to do UTF8 decoding/encoding directly on spans in .NET Standard 2.0, it's possible to get a I'll be working on implementing this soon. |
I'm also planning to work on buffers and handlers to eliminate getting parameter lengths, but will start to do it in July. I think to design buffers like |
@YohDeadfall thanks for the pointer, I'll take a closer look at the corefx lab repo. For now I've concentrated on the simple type handlers, which simply receive a The complex type API is of course a different matter, since type handlers need to be able to perform I/O themselves. I'll work on a good way of doing that and see if anything in corefx lab can be used. Can you say a little bit about what you're planning to do with spans after the above? |
Making high performance API is a good idea, but we shouldn't forget about usability. Therefore, my thoughts on this are:
Let's discuss the new API design first and do great things after. Probably @benaadams could help you too (: |
Good discussion. But before responding, there's one important thing I have to say. I think that changing the type handler API to use Span is a great idea, but I don't expect it to significantly improve performance. Npgsql doesn't currently do any sort of slicing operation anywhere - it's already pretty much a zero-copy driver internally, in that values are simply read from a
Anyway, here are some answers to your comments.
If we keep Npgsql's architecture more or less as it is, I don't really see how buffer pooling would improve perf. The current strategy is simply to permanently attach buffers to physical database connections, which seems to work quite well - we don't need to synchronize in order to get a buffer, we simply use the connection's. One place where things might not be optimal is when the user is reading rows that are bigger than the buffer size, but the latter can be tweaked via the connection string (plus the user has the option to do sequential). So unless we go down the relatively drastic route of implementing multiplexing (#1982), I don't see what problem array/buffer pooling would solve exactly. On the other hand if we do implement multiplexing, buffer pooling becomes a total necessity, since we can no longer buffer on the row - we need to buffer entire resultsets, since resultsets aren't read in order anymore.
Here I assume you're referring to reader/write over a span of bytes, which would allow reading/writing various types (int, float...) a bit like Npgsql's current read/write buffer? AFAIK these types don't exist yet, but I'm guessing you're referring to something in corefx labs.
The API actually used to look like this a long time ago. The reason we don't do auto-flush/ensure, is that these are potentially (although rarely) operations that perform I/O. Because of the virality of async, this would make every single
This is pretty much what I've implemented in my branch (note that it's totally broken work-in-progress, but you can already see this specific change).
You'll have to explain this one a bit more, I don't understand it. |
Hey, is there any decision on working on accepting Span/Memory (more likely the latter, because of the async path)? I tried to follow the comments above but I failed at finding a definitive answer. |
@Scooletz, what exactly are you asking? This issue is about using Span internally inside Npgsql, when reading/writing data from the network. It doesn't affect user APIs in any way (that's another question). Yes, the idea is definitely to switch to using Span, but this is part of a bigger change that may also include switching to the new pipelines API (see #2035). I don't foresee needing Memory (rather than Span) as it's all about populating a buffer in memory before performing the actual I/O write of sending it (or conversely, reading from buffers after they've been populated by an I/O read), so the slice of the buffer in question never needs to live in the heap. |
Oh, I see @roji I totally misinterpreted the discussion and the issue then :-) Sorry for the harassment. |
Most of this is already done and the remaining bits are done in #5123 |
Since it seems like we'll release Npgsql 4.0 at the same time that .NET Core 2.1 comes out, it may be a good idea to use the opportunity the internally switch to Span/Memory - especially in the read/write buffers. At the very least, this will give us access to very optimized primitive reading/writing routines (float, double, int, endian conversion...), and might help in some other areas as well.
@YohDeadfall what do you think?
The text was updated successfully, but these errors were encountered: