From 500ab6a026c5cb39e04ed74c0cbdf9d482035413 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Tue, 29 Sep 2026 16:13:48 +0100 Subject: Put records that come in order straight onto the line, a frame at once A RECORDS frame of records in order, with nothing held and no record's tail waiting, went through hold, on_line and line_append a record: the same checks each time (heard, credit, the line's end, held, the memory bound). Now they are made once for the frame and its records are copied onto the line one after another. The receiver's CPU a 61-byte record in M5 went from 0.15 to 0.133-0.143 us; both sides together 0.28 us, beside ngtcp2's 0.27 and quinn's 0.31 in the same rounds (the M5 host here also compares every record with what was sent). test-link's results are the same to the byte. --- link/link-protocol.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'link') diff --git a/link/link-protocol.c b/link/link-protocol.c index 44aa3e9..7bc4b00 100644 --- a/link/link-protocol.c +++ b/link/link-protocol.c @@ -2187,9 +2187,21 @@ static bool take_from(PureLinkReceiver *s, Peer *peer, const unsigned char *pack unsigned count = plain[at + 8]; at += RECORDS_HEAD - 1; unsigned i = 0; + /* In order, nothing held and no tail waiting: straight onto the + * line, the frame at once (what hold does a record, for all). */ + bool straight = st && st->known && first == line_end(st) && first + count - 1 <= st->heard + CREDIT && + !st->tail && !st->held_count && + st->line_size - st->line_head + (size - at) <= HELD_MOST && + line_room(st, size - at + 4 * (size_t)count); for (size_t used; i < count && (used = get_varint(plain + at, size - at, &length)) && length <= size - at - used; ++i) { - if (st) hold(st, first + i, (uint32_t)length, 0, plain + at + used, (uint32_t)length); + if (straight) { + put32(st->line + st->line_size, (uint32_t)length); + memcpy(st->line + st->line_size + 4, plain + at + used, length); + st->line_size += 4 + length; + ++st->line_count; + } else if (st) + hold(st, first + i, (uint32_t)length, 0, plain + at + used, (uint32_t)length); at += used + length; } if (st) mark_ready(s, st); -- cgit v1.2.3