From b7b2fe14a868efb1727975537ad88deccf3fde7b Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 14 Apr 2026 12:45:23 +0300 Subject: [PATCH] all: This code is in time out (fixes #21319) --- vlib/math/big/bench/bench_edigits.v | 85 +++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 vlib/math/big/bench/bench_edigits.v diff --git a/vlib/math/big/bench/bench_edigits.v b/vlib/math/big/bench/bench_edigits.v new file mode 100644 index 000000000..dcd71fc90 --- /dev/null +++ b/vlib/math/big/bench/bench_edigits.v @@ -0,0 +1,85 @@ +module main + +import benchmark +import math +import math.big +import os +import strconv + +// Regression benchmark for issue #21319. +// It mirrors the external edigits workload without printing every line, +// so the timing stays focused on `math.big`. +const default_n = 250_001 +const one = big.one_int +const ten = big.c10 + +fn main() { + mut n := default_n + if os.args.len > 1 { + n = strconv.atoi(os.args[1]) or { default_n } + } + mut clock := benchmark.start() + k := binary_search(n) + clock.measure('k=${k}') + mut p, q := sum_terms(0, k - 1) + clock.measure('sum_terms p.bit_len=${p.bit_len()} q.bit_len=${q.bit_len()}') + p += q + a := ten.pow(u32(n - 1)) + clock.measure('pow 10^${n - 1}') + answer := p * a / q + clock.measure('division answer.bit_len=${answer.bit_len()}') + s := answer.str() + clock.measure('str digits=${s.len}') + if s.len != n { + eprintln('unexpected digit count: got ${s.len}, want ${n}') + return + } + println(last_line(s, n)) +} + +fn sum_terms(a int, b int) (big.Integer, big.Integer) { + if b == a + 1 { + return one, big.integer_from_int(b) + } + mid := (a + b) / 2 + p_left, q_left := sum_terms(a, mid) + p_right, q_right := sum_terms(mid, b) + return p_left * q_right + p_right, q_left * q_right +} + +fn binary_search(n int) int { + mut a := 0 + mut b := 1 + for !test_k(n, b) { + a = b + b *= 2 + } + for b - a > 1 { + m := (a + b) / 2 + if test_k(n, m) { + b = m + } else { + a = m + } + } + return b +} + +fn test_k(n int, k int) bool { + if k < 0 { + return false + } + ln_k_factorial := k * (math.log(k) - 1) + 0.5 * math.log(math.tau) + log_10_k_factorial := ln_k_factorial / math.ln10 + return log_10_k_factorial >= n + 50 +} + +fn last_line(s string, n int) string { + chunk_len := if n % 10 == 0 { 10 } else { n % 10 } + start := n - chunk_len + mut line := s[start..n] + for line.len < 10 { + line += ' ' + } + return '${line}\t:${n}' +} -- 2.39.5