From a3a139317ed2e511adce54ef0b099b105f0f070a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Tue, 9 Jan 2024 20:08:53 +0100 Subject: [PATCH 01/10] feat() add benchmarks --- Makefile | 4 +++ fhevm/benchmarks_test.go | 70 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 fhevm/benchmarks_test.go diff --git a/Makefile b/Makefile index d83dff6..b630fca 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,10 @@ build: build-tfhe-rs-capi test: build-tfhe-rs-capi cd fhevm && go test -v . +.PHONY: benchmarks +benchmarks: build-tfhe-rs-capi + cd fhevm && go test -v . -run Benchmarks + .PHONY: build-tfhe-rs-capi build-tfhe-rs-capi: cd tfhe-rs && RUSTFLAGS="" make build_c_api_experimental_deterministic_fft \ diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go new file mode 100644 index 0000000..4458395 --- /dev/null +++ b/fhevm/benchmarks_test.go @@ -0,0 +1,70 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package fhevm + +import ( + "testing" + "time" +) + +type operation func(FheUintType) + + + +func convertInGas(t *testing.T, name string, elapsed [3]time.Duration) { + sum := int64(0) + for i := 0; i < 3; i++ { + sum += int64(elapsed[i]) + } + + avg := sum / 3 + gasUsed := avg / 1000 // 1s = 1 000 000 gas + gasUsed = gasUsed / 7 * 10 // 1s = 100k + gasUsed = gasUsed / 1000 // divide to round it + t.Logf("%s in %s => %d", name, elapsed, gasUsed * 1000) +} + +func runTest(t *testing.T, name string, fn operation, bits string, fheUintType FheUintType) { + var elapsed [3]time.Duration + n := 0 + for n < 3 { + start := time.Now() + fn(fheUintType) + elapsed[n] = time.Since(start) + n += 1 + } + convertInGas(t, name + bits, elapsed) +} + +func benchTests(t *testing.T, name string, fn operation) { + runTest(t, name, fn, "8", FheUint8) + runTest(t, name, fn, "16", FheUint16) + runTest(t, name, fn, "32", FheUint32) +} + +func TestBenchmarks(t *testing.T) { + benchTests(t, "add", func(fheUintType FheUintType) { FheAdd(t, fheUintType, false) }) + benchTests(t, "ScalarAdd", func(fheUintType FheUintType) { FheAdd(t, fheUintType, true) }) + + benchTests(t, "sub", func(fheUintType FheUintType) { FheSub(t, fheUintType, false) }) + benchTests(t, "ScalarSub", func(fheUintType FheUintType) { FheSub(t, fheUintType, true) }) + + benchTests(t, "mul", func(fheUintType FheUintType) { FheMul(t, fheUintType, false) }) + benchTests(t, "ScalarMul", func(fheUintType FheUintType) { FheMul(t, fheUintType, true) }) + + benchTests(t, "ScalarDiv", func(fheUintType FheUintType) { FheDiv(t, fheUintType, true) }) +} From 0d193293943465937d9d64a72842af70ca8ff89a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Wed, 10 Jan 2024 10:43:19 +0100 Subject: [PATCH 02/10] feat() add more benchmarks --- Makefile | 2 +- fhevm/benchmarks_test.go | 45 ++++++++++++++++++++++++++-------------- fhevm/contracts_test.go | 6 +++--- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index b630fca..556b0c8 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ test: build-tfhe-rs-capi .PHONY: benchmarks benchmarks: build-tfhe-rs-capi - cd fhevm && go test -v . -run Benchmarks + cd fhevm && go test -count=1 -v . -run Benchmarks .PHONY: build-tfhe-rs-capi build-tfhe-rs-capi: diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go index 4458395..6cd69f0 100644 --- a/fhevm/benchmarks_test.go +++ b/fhevm/benchmarks_test.go @@ -19,29 +19,35 @@ package fhevm import ( "testing" "time" + "sync" ) type operation func(FheUintType) +const numBenchmarkRuns = 10 +func convertInGas(t *testing.T, name string, elapsed [numBenchmarkRuns]time.Duration) { + lowest := elapsed[0] -func convertInGas(t *testing.T, name string, elapsed [3]time.Duration) { - sum := int64(0) - for i := 0; i < 3; i++ { - sum += int64(elapsed[i]) + // Find the lowest duration in the array + for i := 1; i < numBenchmarkRuns; i++ { + if elapsed[i] < lowest { + lowest = elapsed[i] + } } - - avg := sum / 3 - gasUsed := avg / 1000 // 1s = 1 000 000 gas - gasUsed = gasUsed / 7 * 10 // 1s = 100k - gasUsed = gasUsed / 1000 // divide to round it - t.Logf("%s in %s => %d", name, elapsed, gasUsed * 1000) + + gasUsed := int64(lowest) / 1000 // 1s = 1,000,000 gas + gasUsed = gasUsed / 7 * 10 // 1s = 100k + gasUsed = gasUsed / 1000 // Divide to round it + + t.Logf("%s in %s => %d", name, lowest, gasUsed*1000) } -func runTest(t *testing.T, name string, fn operation, bits string, fheUintType FheUintType) { - var elapsed [3]time.Duration +func runTest(t *testing.T, name string, fn operation, bits string, fheUintType FheUintType, wg *sync.WaitGroup) { + defer wg.Done() + var elapsed [numBenchmarkRuns]time.Duration n := 0 - for n < 3 { + for n < numBenchmarkRuns { start := time.Now() fn(fheUintType) elapsed[n] = time.Since(start) @@ -51,9 +57,14 @@ func runTest(t *testing.T, name string, fn operation, bits string, fheUintType F } func benchTests(t *testing.T, name string, fn operation) { - runTest(t, name, fn, "8", FheUint8) - runTest(t, name, fn, "16", FheUint16) - runTest(t, name, fn, "32", FheUint32) + var wg sync.WaitGroup + wg.Add(3) + + go runTest(t, name, fn, "8", FheUint8, &wg) + go runTest(t, name, fn, "16", FheUint16, &wg) + go runTest(t, name, fn, "32", FheUint32, &wg) + + wg.Wait() } func TestBenchmarks(t *testing.T) { @@ -67,4 +78,6 @@ func TestBenchmarks(t *testing.T) { benchTests(t, "ScalarMul", func(fheUintType FheUintType) { FheMul(t, fheUintType, true) }) benchTests(t, "ScalarDiv", func(fheUintType FheUintType) { FheDiv(t, fheUintType, true) }) + + benchTests(t, "IfThenElse", func(fheUintType FheUintType) { FheIfThenElse(t, fheUintType, 1) }) } diff --git a/fhevm/contracts_test.go b/fhevm/contracts_test.go index 7ee675c..ab47129 100644 --- a/fhevm/contracts_test.go +++ b/fhevm/contracts_test.go @@ -1597,7 +1597,7 @@ func FheMul(t *testing.T, fheUintType FheUintType, scalar bool) { switch fheUintType { case FheUint8: lhs = 2 - rhs = 1 + rhs = 3 case FheUint16: lhs = 169 rhs = 5 @@ -1637,8 +1637,8 @@ func FheDiv(t *testing.T, fheUintType FheUintType, scalar bool) { var lhs, rhs uint64 switch fheUintType { case FheUint8: - lhs = 4 - rhs = 2 + lhs = 6 + rhs = 3 case FheUint16: lhs = 721 rhs = 1000 From 9c08a502a18966a5cb0818ce2b00287a20fa8530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Wed, 10 Jan 2024 15:54:02 +0100 Subject: [PATCH 03/10] feat() update list of ops --- fhevm/benchmarks_test.go | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go index 6cd69f0..7774d87 100644 --- a/fhevm/benchmarks_test.go +++ b/fhevm/benchmarks_test.go @@ -19,7 +19,6 @@ package fhevm import ( "testing" "time" - "sync" ) type operation func(FheUintType) @@ -37,14 +36,13 @@ func convertInGas(t *testing.T, name string, elapsed [numBenchmarkRuns]time.Dura } gasUsed := int64(lowest) / 1000 // 1s = 1,000,000 gas - gasUsed = gasUsed / 7 * 10 // 1s = 100k + gasUsed = gasUsed / 7 * 10 // 0.7s = 1,000,000 gas gasUsed = gasUsed / 1000 // Divide to round it t.Logf("%s in %s => %d", name, lowest, gasUsed*1000) } -func runTest(t *testing.T, name string, fn operation, bits string, fheUintType FheUintType, wg *sync.WaitGroup) { - defer wg.Done() +func runTest(t *testing.T, name string, fn operation, bits string, fheUintType FheUintType) { var elapsed [numBenchmarkRuns]time.Duration n := 0 for n < numBenchmarkRuns { @@ -57,17 +55,23 @@ func runTest(t *testing.T, name string, fn operation, bits string, fheUintType F } func benchTests(t *testing.T, name string, fn operation) { - var wg sync.WaitGroup - wg.Add(3) - - go runTest(t, name, fn, "8", FheUint8, &wg) - go runTest(t, name, fn, "16", FheUint16, &wg) - go runTest(t, name, fn, "32", FheUint32, &wg) - - wg.Wait() + runTest(t, name, fn, "8", FheUint8) + runTest(t, name, fn, "16", FheUint16) + runTest(t, name, fn, "32", FheUint32) } func TestBenchmarks(t *testing.T) { + benchTests(t, "and", func(fheUintType FheUintType) { FheBitAnd(t, fheUintType, false) }) + + benchTests(t, "eq", func(fheUintType FheUintType) { FheEq(t, fheUintType, false) }) + benchTests(t, "ScalarEq", func(fheUintType FheUintType) { FheEq(t, fheUintType, true) }) + + benchTests(t, "shr", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) + benchTests(t, "ScalarShr", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) + + benchTests(t, "min", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) + benchTests(t, "ScalarMin", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) + benchTests(t, "add", func(fheUintType FheUintType) { FheAdd(t, fheUintType, false) }) benchTests(t, "ScalarAdd", func(fheUintType FheUintType) { FheAdd(t, fheUintType, true) }) From c132a187c95660bfd85882f447b208b6f9844c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Wed, 10 Jan 2024 18:50:50 +0100 Subject: [PATCH 04/10] fix() reduce number of exec --- fhevm/benchmarks_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go index 7774d87..3dc1aca 100644 --- a/fhevm/benchmarks_test.go +++ b/fhevm/benchmarks_test.go @@ -23,7 +23,7 @@ import ( type operation func(FheUintType) -const numBenchmarkRuns = 10 +const numBenchmarkRuns = 5 func convertInGas(t *testing.T, name string, elapsed [numBenchmarkRuns]time.Duration) { lowest := elapsed[0] From c29de033f39675bd54ff89f555096f884cf6570c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Wed, 10 Jan 2024 19:25:07 +0100 Subject: [PATCH 05/10] feat() add not benchmark --- fhevm/benchmarks_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go index 3dc1aca..fdd2b0c 100644 --- a/fhevm/benchmarks_test.go +++ b/fhevm/benchmarks_test.go @@ -48,10 +48,10 @@ func runTest(t *testing.T, name string, fn operation, bits string, fheUintType F for n < numBenchmarkRuns { start := time.Now() fn(fheUintType) - elapsed[n] = time.Since(start) + elapsed[n] = time.Since(start) n += 1 } - convertInGas(t, name + bits, elapsed) + convertInGas(t, name+bits, elapsed) } func benchTests(t *testing.T, name string, fn operation) { @@ -61,6 +61,8 @@ func benchTests(t *testing.T, name string, fn operation) { } func TestBenchmarks(t *testing.T) { + benchTests(t, "not", func(fheUintType FheUintType) { FheNot(t, fheUintType, false) }) + benchTests(t, "and", func(fheUintType FheUintType) { FheBitAnd(t, fheUintType, false) }) benchTests(t, "eq", func(fheUintType FheUintType) { FheEq(t, fheUintType, false) }) From a9c944c55f8fe35643d4224fc88fcc8e1d415683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Thu, 11 Jan 2024 14:40:10 +0100 Subject: [PATCH 06/10] increase divider for scalar --- fhevm/benchmarks_test.go | 16 ---------------- fhevm/contracts_test.go | 6 +++--- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go index fdd2b0c..7211c03 100644 --- a/fhevm/benchmarks_test.go +++ b/fhevm/benchmarks_test.go @@ -1,19 +1,3 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - package fhevm import ( diff --git a/fhevm/contracts_test.go b/fhevm/contracts_test.go index ab47129..d1394bf 100644 --- a/fhevm/contracts_test.go +++ b/fhevm/contracts_test.go @@ -1638,13 +1638,13 @@ func FheDiv(t *testing.T, fheUintType FheUintType, scalar bool) { switch fheUintType { case FheUint8: lhs = 6 - rhs = 3 + rhs = 7 case FheUint16: lhs = 721 - rhs = 1000 + rhs = 251 case FheUint32: lhs = 137 - rhs = 17 + rhs = 65521 } expected := lhs / rhs depth := 1 From a9bbd8fa6f0176a128943b92509eb24c628b2960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Danjou?= Date: Mon, 15 Jan 2024 11:01:49 +0100 Subject: [PATCH 07/10] fix() typo --- fhevm/benchmarks_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go index 7211c03..8031bb5 100644 --- a/fhevm/benchmarks_test.go +++ b/fhevm/benchmarks_test.go @@ -55,8 +55,8 @@ func TestBenchmarks(t *testing.T) { benchTests(t, "shr", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) benchTests(t, "ScalarShr", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) - benchTests(t, "min", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) - benchTests(t, "ScalarMin", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) + benchTests(t, "min", func(fheUintType FheUintType) { FheShr(t, fheUintType, false) }) + benchTests(t, "ScalarMin", func(fheUintType FheUintType) { FheShr(t, fheUintType, true) }) benchTests(t, "add", func(fheUintType FheUintType) { FheAdd(t, fheUintType, false) }) benchTests(t, "ScalarAdd", func(fheUintType FheUintType) { FheAdd(t, fheUintType, true) }) From 2c6ab9c0f554d957394fb18463e9b67d312bf25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Danjou?= Date: Mon, 15 Jan 2024 11:02:52 +0100 Subject: [PATCH 08/10] fix() fix typo :D --- fhevm/benchmarks_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go index 8031bb5..ef57018 100644 --- a/fhevm/benchmarks_test.go +++ b/fhevm/benchmarks_test.go @@ -52,11 +52,11 @@ func TestBenchmarks(t *testing.T) { benchTests(t, "eq", func(fheUintType FheUintType) { FheEq(t, fheUintType, false) }) benchTests(t, "ScalarEq", func(fheUintType FheUintType) { FheEq(t, fheUintType, true) }) - benchTests(t, "shr", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) - benchTests(t, "ScalarShr", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) + benchTests(t, "shr", func(fheUintType FheUintType) { FheShr(t, fheUintType, false) }) + benchTests(t, "ScalarShr", func(fheUintType FheUintType) { FheShr(t, fheUintType, true) }) - benchTests(t, "min", func(fheUintType FheUintType) { FheShr(t, fheUintType, false) }) - benchTests(t, "ScalarMin", func(fheUintType FheUintType) { FheShr(t, fheUintType, true) }) + benchTests(t, "min", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) + benchTests(t, "ScalarMin", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) benchTests(t, "add", func(fheUintType FheUintType) { FheAdd(t, fheUintType, false) }) benchTests(t, "ScalarAdd", func(fheUintType FheUintType) { FheAdd(t, fheUintType, true) }) From 2966b7b3830f80414a86262a6ef8e0bde010c31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Danjou?= Date: Mon, 15 Jan 2024 11:20:19 +0100 Subject: [PATCH 09/10] fix() change the shift to a non-power of 2 --- fhevm/contracts_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fhevm/contracts_test.go b/fhevm/contracts_test.go index d1394bf..3f46850 100644 --- a/fhevm/contracts_test.go +++ b/fhevm/contracts_test.go @@ -731,7 +731,7 @@ func FheLibShr(t *testing.T, fheUintType FheUintType, scalar bool) { rhs = 1 case FheUint16: lhs = 4283 - rhs = 2 + rhs = 3 case FheUint32: lhs = 1333337 rhs = 3 @@ -1917,7 +1917,7 @@ func FheShr(t *testing.T, fheUintType FheUintType, scalar bool) { rhs = 1 case FheUint16: lhs = 4283 - rhs = 2 + rhs = 3 case FheUint32: lhs = 1333337 rhs = 3 From 22edf6e9b8b97f0ebf4c52f46ead38e4572ac38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20=27birdy=27=20Danjou?= Date: Wed, 17 Jan 2024 10:56:09 +0100 Subject: [PATCH 10/10] fix() rename benchmarks to gas estimation --- Makefile | 6 +-- fhevm/benchmarks_test.go | 73 ------------------------------------- fhevm/gasEstimation_test.go | 73 +++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 76 deletions(-) delete mode 100644 fhevm/benchmarks_test.go create mode 100644 fhevm/gasEstimation_test.go diff --git a/Makefile b/Makefile index 556b0c8..d26b514 100644 --- a/Makefile +++ b/Makefile @@ -6,9 +6,9 @@ build: build-tfhe-rs-capi test: build-tfhe-rs-capi cd fhevm && go test -v . -.PHONY: benchmarks -benchmarks: build-tfhe-rs-capi - cd fhevm && go test -count=1 -v . -run Benchmarks +.PHONY: gasEstimation +gasEstimation: build-tfhe-rs-capi + cd fhevm && go test -count=1 -v . -run GasEstimation .PHONY: build-tfhe-rs-capi build-tfhe-rs-capi: diff --git a/fhevm/benchmarks_test.go b/fhevm/benchmarks_test.go deleted file mode 100644 index ef57018..0000000 --- a/fhevm/benchmarks_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package fhevm - -import ( - "testing" - "time" -) - -type operation func(FheUintType) - -const numBenchmarkRuns = 5 - -func convertInGas(t *testing.T, name string, elapsed [numBenchmarkRuns]time.Duration) { - lowest := elapsed[0] - - // Find the lowest duration in the array - for i := 1; i < numBenchmarkRuns; i++ { - if elapsed[i] < lowest { - lowest = elapsed[i] - } - } - - gasUsed := int64(lowest) / 1000 // 1s = 1,000,000 gas - gasUsed = gasUsed / 7 * 10 // 0.7s = 1,000,000 gas - gasUsed = gasUsed / 1000 // Divide to round it - - t.Logf("%s in %s => %d", name, lowest, gasUsed*1000) -} - -func runTest(t *testing.T, name string, fn operation, bits string, fheUintType FheUintType) { - var elapsed [numBenchmarkRuns]time.Duration - n := 0 - for n < numBenchmarkRuns { - start := time.Now() - fn(fheUintType) - elapsed[n] = time.Since(start) - n += 1 - } - convertInGas(t, name+bits, elapsed) -} - -func benchTests(t *testing.T, name string, fn operation) { - runTest(t, name, fn, "8", FheUint8) - runTest(t, name, fn, "16", FheUint16) - runTest(t, name, fn, "32", FheUint32) -} - -func TestBenchmarks(t *testing.T) { - benchTests(t, "not", func(fheUintType FheUintType) { FheNot(t, fheUintType, false) }) - - benchTests(t, "and", func(fheUintType FheUintType) { FheBitAnd(t, fheUintType, false) }) - - benchTests(t, "eq", func(fheUintType FheUintType) { FheEq(t, fheUintType, false) }) - benchTests(t, "ScalarEq", func(fheUintType FheUintType) { FheEq(t, fheUintType, true) }) - - benchTests(t, "shr", func(fheUintType FheUintType) { FheShr(t, fheUintType, false) }) - benchTests(t, "ScalarShr", func(fheUintType FheUintType) { FheShr(t, fheUintType, true) }) - - benchTests(t, "min", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) - benchTests(t, "ScalarMin", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) - - benchTests(t, "add", func(fheUintType FheUintType) { FheAdd(t, fheUintType, false) }) - benchTests(t, "ScalarAdd", func(fheUintType FheUintType) { FheAdd(t, fheUintType, true) }) - - benchTests(t, "sub", func(fheUintType FheUintType) { FheSub(t, fheUintType, false) }) - benchTests(t, "ScalarSub", func(fheUintType FheUintType) { FheSub(t, fheUintType, true) }) - - benchTests(t, "mul", func(fheUintType FheUintType) { FheMul(t, fheUintType, false) }) - benchTests(t, "ScalarMul", func(fheUintType FheUintType) { FheMul(t, fheUintType, true) }) - - benchTests(t, "ScalarDiv", func(fheUintType FheUintType) { FheDiv(t, fheUintType, true) }) - - benchTests(t, "IfThenElse", func(fheUintType FheUintType) { FheIfThenElse(t, fheUintType, 1) }) -} diff --git a/fhevm/gasEstimation_test.go b/fhevm/gasEstimation_test.go new file mode 100644 index 0000000..d747627 --- /dev/null +++ b/fhevm/gasEstimation_test.go @@ -0,0 +1,73 @@ +package fhevm + +import ( + "testing" + "time" +) + +type operation func(FheUintType) + +const numBenchmarkRuns = 5 + +func convertInGas(t *testing.T, name string, elapsed [numBenchmarkRuns]time.Duration) { + lowest := elapsed[0] + + // Find the lowest duration in the array + for i := 1; i < numBenchmarkRuns; i++ { + if elapsed[i] < lowest { + lowest = elapsed[i] + } + } + + gasUsed := int64(lowest) / 1000 // 1s = 1,000,000 gas + gasUsed = gasUsed / 7 * 10 // 0.7s = 1,000,000 gas + gasUsed = gasUsed / 1000 // Divide to round it + + t.Logf("%s in %s => %d", name, lowest, gasUsed*1000) +} + +func runTest(t *testing.T, name string, fn operation, bits string, fheUintType FheUintType) { + var elapsed [numBenchmarkRuns]time.Duration + n := 0 + for n < numBenchmarkRuns { + start := time.Now() + fn(fheUintType) + elapsed[n] = time.Since(start) + n += 1 + } + convertInGas(t, name+bits, elapsed) +} + +func estimateTests(t *testing.T, name string, fn operation) { + runTest(t, name, fn, "8", FheUint8) + runTest(t, name, fn, "16", FheUint16) + runTest(t, name, fn, "32", FheUint32) +} + +func TestGasEstimation(t *testing.T) { + estimateTests(t, "not", func(fheUintType FheUintType) { FheNot(t, fheUintType, false) }) + + estimateTests(t, "and", func(fheUintType FheUintType) { FheBitAnd(t, fheUintType, false) }) + + estimateTests(t, "eq", func(fheUintType FheUintType) { FheEq(t, fheUintType, false) }) + estimateTests(t, "ScalarEq", func(fheUintType FheUintType) { FheEq(t, fheUintType, true) }) + + estimateTests(t, "shr", func(fheUintType FheUintType) { FheShr(t, fheUintType, false) }) + estimateTests(t, "ScalarShr", func(fheUintType FheUintType) { FheShr(t, fheUintType, true) }) + + estimateTests(t, "min", func(fheUintType FheUintType) { FheMin(t, fheUintType, false) }) + estimateTests(t, "ScalarMin", func(fheUintType FheUintType) { FheMin(t, fheUintType, true) }) + + estimateTests(t, "add", func(fheUintType FheUintType) { FheAdd(t, fheUintType, false) }) + estimateTests(t, "ScalarAdd", func(fheUintType FheUintType) { FheAdd(t, fheUintType, true) }) + + estimateTests(t, "sub", func(fheUintType FheUintType) { FheSub(t, fheUintType, false) }) + estimateTests(t, "ScalarSub", func(fheUintType FheUintType) { FheSub(t, fheUintType, true) }) + + estimateTests(t, "mul", func(fheUintType FheUintType) { FheMul(t, fheUintType, false) }) + estimateTests(t, "ScalarMul", func(fheUintType FheUintType) { FheMul(t, fheUintType, true) }) + + estimateTests(t, "ScalarDiv", func(fheUintType FheUintType) { FheDiv(t, fheUintType, true) }) + + estimateTests(t, "IfThenElse", func(fheUintType FheUintType) { FheIfThenElse(t, fheUintType, 1) }) +}