From a5892302492868246c4612575fa50b4a8f41ef6e Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Sun, 26 Aug 2018 02:23:26 +0800 Subject: [PATCH] Faster path for varint read. clickhouse-benchmark <<< 'select count() from s where not ignore(s);' before this patch: ``` QPS: 0.732, RPS: 2346562049.608, MiB/s: 22378.560, result RPS: 0.732, result MiB/s: 0.000. 0.000% 1.310 sec. 10.000% 1.321 sec. 20.000% 1.327 sec. 30.000% 1.337 sec. 40.000% 1.343 sec. 50.000% 1.359 sec. 60.000% 1.366 sec. 70.000% 1.381 sec. 80.000% 1.400 sec. 90.000% 1.434 sec. 95.000% 1.448 sec. 99.000% 1.489 sec. 99.900% 1.499 sec. 99.990% 1.500 sec. ``` after this patch: ``` QPS: 0.787, RPS: 2524560389.064, MiB/s: 24076.084, result RPS: 0.787, result MiB/s: 0.000. 0.000% 1.228 sec. 10.000% 1.232 sec. 20.000% 1.235 sec. 30.000% 1.241 sec. 40.000% 1.246 sec. 50.000% 1.256 sec. 60.000% 1.265 sec. 70.000% 1.278 sec. 80.000% 1.296 sec. 90.000% 1.321 sec. 95.000% 1.354 sec. 99.000% 1.421 sec. 99.900% 1.453 sec. 99.990% 1.456 sec. ``` I also tried a SSE2 implementation and it's much slower (50%) --- dbms/src/IO/VarInt.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/dbms/src/IO/VarInt.h b/dbms/src/IO/VarInt.h index 73a404e037e..25b8013a24c 100644 --- a/dbms/src/IO/VarInt.h +++ b/dbms/src/IO/VarInt.h @@ -118,13 +118,15 @@ inline void throwReadAfterEOF() throw Exception("Attempt to read after eof", ErrorCodes::ATTEMPT_TO_READ_AFTER_EOF); } -inline void readVarUInt(UInt64 & x, ReadBuffer & istr) +template +inline void readVarUIntImpl(UInt64 & x, ReadBuffer & istr) { x = 0; for (size_t i = 0; i < 9; ++i) { - if (istr.eof()) - throwReadAfterEOF(); + if constexpr (!fast) + if (istr.eof()) + throwReadAfterEOF(); UInt64 byte = *istr.position(); ++istr.position(); @@ -135,6 +137,13 @@ inline void readVarUInt(UInt64 & x, ReadBuffer & istr) } } +inline void readVarUInt(UInt64 & x, ReadBuffer & istr) +{ + if (istr.buffer().end() - istr.position() >= 9) + return readVarUIntImpl(x, istr); + return readVarUIntImpl(x, istr); +} + inline void readVarUInt(UInt64 & x, std::istream & istr) {