Skip to content

Commit

Permalink
Cheaper calculation of flushes. (#264)
Browse files Browse the repository at this point in the history
Motivation:

The outbound flow control buffer currently does a linear scan through
the pending data objects to work out how many bytes were buffered. Let's
burn an integer and just calculate these on the way in, making flushes
way cheaper.

Modifications:

- Update the number of bytes when we buffer the write, and make flushes
  cheaper.

Result:

Moderate performance improvement in high throughput server benchmarks
(around 4%).
  • Loading branch information
Lukasa authored Nov 30, 2020
1 parent c61955a commit 2f3c6e7
Showing 1 changed file with 10 additions and 15 deletions.
25 changes: 10 additions & 15 deletions Sources/NIOHTTP2/Frame Buffers/OutboundFlowControlBuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ private struct DataBuffer {

internal private(set) var flushedBufferedBytes: UInt

private var unflushedBufferedBytes: UInt

var haveBufferedDataFrame: Bool {
return self.bufferedChunks.count > 0
}
Expand All @@ -254,29 +256,22 @@ private struct DataBuffer {
init() {
self.bufferedChunks = MarkedCircularBuffer(initialCapacity: 8)
self.flushedBufferedBytes = 0
self.unflushedBufferedBytes = 0
}

mutating func bufferWrite(_ write: BufferElement) {
if case .data(let contents) = write.0 {
self.unflushedBufferedBytes += UInt(contents.data.readableBytes)
}

self.bufferedChunks.append(write)
}

/// Marks the current point in the buffer as the place up to which we have flushed.
mutating func markFlushPoint() {
if let markIndex = self.bufferedChunks.markedElementIndex {
for element in self.bufferedChunks.suffix(from: markIndex) {
if case .data(let contents) = element.0 {
self.flushedBufferedBytes += UInt(contents.data.readableBytes)
}
}
self.bufferedChunks.mark()
} else if self.bufferedChunks.count > 0 {
for element in self.bufferedChunks {
if case .data(let contents) = element.0 {
self.flushedBufferedBytes += UInt(contents.data.readableBytes)
}
}
self.bufferedChunks.mark()
}
self.flushedBufferedBytes += self.unflushedBufferedBytes
self.unflushedBufferedBytes = 0
self.bufferedChunks.mark()
}

mutating func nextWrite(maxSize: Int) -> BufferElement {
Expand Down

0 comments on commit 2f3c6e7

Please sign in to comment.