From 074020906efda3354ba0db907579ed14d20dd662 Mon Sep 17 00:00:00 2001 From: ruslandoga Date: Sat, 19 Jul 2025 16:48:51 +0300 Subject: [PATCH] wip --- bench/varint.exs | 38 ++++++++++++++++++++++++++++++++++++++ lib/ch/row_binary.ex | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 bench/varint.exs diff --git a/bench/varint.exs b/bench/varint.exs new file mode 100644 index 00000000..92f6cf7f --- /dev/null +++ b/bench/varint.exs @@ -0,0 +1,38 @@ +Benchee.run( + %{ + "old" => fn input -> Enum.each(input, &Ch.RowBinary.encode_varint/1) end, + "new" => fn input -> Enum.each(input, &Ch.RowBinary.encode_varint_new/1) end + }, + inputs: %{ + "small" => Enum.to_list(0..10000), + "medium" => Enum.to_list(100_000..110_000), + "large" => Enum.to_list(10_000_000..10_010_000) + } +) + +# ##### With input large ##### +# Name ips average deviation median 99th % +# new 11.16 K 89.57 μs ±4.27% 89.04 μs 104.63 μs +# old 4.79 K 208.97 μs ±3.67% 207.54 μs 242.17 μs + +# Comparison: +# new 11.16 K +# old 4.79 K - 2.33x slower +119.40 μs + +# ##### With input medium ##### +# Name ips average deviation median 99th % +# new 12.59 K 79.41 μs ±4.36% 78.96 μs 93.58 μs +# old 6.05 K 165.30 μs ±3.81% 164.17 μs 183.21 μs + +# Comparison: +# new 12.59 K +# old 6.05 K - 2.08x slower +85.89 μs + +# ##### With input small ##### +# Name ips average deviation median 99th % +# new 14.53 K 68.82 μs ±4.09% 68.50 μs 80.67 μs +# old 8.23 K 121.52 μs ±3.67% 120.83 μs 135.03 μs + +# Comparison: +# new 14.53 K +# old 8.23 K - 1.77x slower +52.70 μs diff --git a/lib/ch/row_binary.ex b/lib/ch/row_binary.ex index fbd77d45..dc675248 100644 --- a/lib/ch/row_binary.ex +++ b/lib/ch/row_binary.ex @@ -178,6 +178,38 @@ defmodule Ch.RowBinary do raise ArgumentError, "unsupported type for encoding: #{inspect(type)}" end + @doc false + def encode_varint(i) when is_integer(i) and i < 128, do: i + def encode_varint(i) when is_integer(i), do: encode_varint_cont(i) + + @doc false + def encode_varint_new(v) when v < 1 <<< 7, do: v + def encode_varint_new(v) when v < 1 <<< 14, do: <<1::1, v::7, v >>> 7>> + def encode_varint_new(v) when v < 1 <<< 21, do: <<1::1, v::7, 1::1, v >>> 7::7, v >>> 14>> + + def encode_varint_new(v) when v < 1 <<< 28, + do: <<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, v >>> 21>> + + def encode_varint_new(v) when v < 1 <<< 35, + do: <<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, v >>> 28>> + + def encode_varint_new(v) when v < 1 <<< 42, + do: + <<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, 1::1, v >>> 28::7, + v >>> 35>> + + def encode_varint_new(v) when v < 1 <<< 49, + do: + <<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, 1::1, v >>> 28::7, + 1::1, v >>> 35::7, v >>> 42>> + + def encode_varint_new(v) when v < 1 <<< 56, + do: + <<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, 1::1, v >>> 28::7, + 1::1, v >>> 35::7, 1::1, v >>> 42::7, v >>> 49>> + + def encode_varint_new(v), do: <<1::1, v::7, encode_varint_new(v >>> 7)::bytes>> + @doc false def encode(type, value)