Files
fission-console/bench_heavy.py
T

1107 lines
33 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Создаёт/обновляет 6 benchmark-функций с ~10KB кода и тяжёлой вычислительной нагрузкой.
Случайные задержки, матрицы, сортировки, хэши — настоящая нагрузка.
"""
import json, subprocess, sys
BASE = "https://fission.kube5s.ru/console/api"
SUB = "livetest@test.local"
# ── Node.js ──────────────────────────────────────────────────────────────────
NODE_CODE = r"""module.exports = async (ctx) => {
// ~10KB of real CPU work + async delays with random timing
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
function millerRabin(n) {
if (n < 2) return false; if (n===2||n===3||n===5||n===7) return true;
if (n%2===0) return false;
let d=n-1, r=0; while(d%2===0){d/=2;r++;}
const witnesses=[2,3,5,7,11,13,17,19,23,29,31,37];
for(const a of witnesses){
if(a>=n)continue; let x=modPow(a,d,n);
if(x===1||x===n-1)continue; let cont=false;
for(let i=0;i<r-1;i++){x=modPow(x,2,n);if(x===n-1){cont=true;break;}}
if(!cont)return false;
}
return true;
}
function modPow(base,exp,mod){
let result=1n,b=BigInt(base),e=BigInt(exp),m=BigInt(mod);
b%=m; while(e>0n){if(e%2n===1n)result=result*b%m;e>>=1n;b=b*b%m;}
return Number(result);
}
function gcd(a,b){while(b){[a,b]=[b,a%b];}return a;}
function lcm(a,b){return a/gcd(a,b)*b;}
function lucas(n){
if(n===0)return 2; if(n===1)return 1;
let a=2,b=1; for(let i=2;i<=n;i++){let t=a+b;a=b;b=t;} return b;
}
function fnv1a(str){
let h=2166136261>>>0;
for(let i=0;i<str.length;i++){h^=str.charCodeAt(i);h=Math.imul(h,16777619)>>>0;}
return h;
}
function collatz(n){let s=0;while(n!==1){n=n%2===0?n/2:3*n+1;s++;}return s;}
function hornerEval(coeffs,x){
let r=0; for(let i=coeffs.length-1;i>=0;i--)r=r*x+coeffs[i]; return r;
}
function digitSum(n){let s=0;while(n>0){s+=n%10;n=Math.floor(n/10);}return s;}
function sundaramSieve(n){
const lim=Math.floor((n-2)/2);
const s=new Array(lim+1).fill(false);
for(let i=1;i<=lim;i++) for(let j=i;i+j+2*i*j<=lim;j++) s[i+j+2*i*j]=true;
const primes=[2];
for(let i=1;i<=lim;i++) if(!s[i]) primes.push(2*i+1);
return primes;
}
function rleEncode(arr){
if(!arr.length)return[];
const out=[];let cur=arr[0],cnt=1;
for(let i=1;i<arr.length;i++){if(arr[i]===cur)cnt++;else{out.push([cur,cnt]);cur=arr[i];cnt=1;}}
out.push([cur,cnt]);return out;
}
function heapSort(arr){
const a=[...arr],n=a.length;
function heapify(i,size){let l=2*i+1,r=2*i+2,m=i;if(l<size&&a[l]>a[m])m=l;if(r<size&&a[r]>a[m])m=r;if(m!==i){[a[i],a[m]]=[a[m],a[i]];heapify(m,size);}}
for(let i=Math.floor(n/2)-1;i>=0;i--)heapify(i,n);
for(let i=n-1;i>0;i--){[a[0],a[i]]=[a[i],a[0]];heapify(0,i);}
return a;
}
function fib(n) {
if (n <= 1) return n;
let a = 0, b = 1;
for (let i = 2; i <= n; i++) { let t = a + b; a = b; b = t; }
return b;
}
function isPrime(n) {
if (n < 2) return false;
if (n === 2) return true;
if (n % 2 === 0) return false;
for (let i = 3; i * i <= n; i += 2) if (n % i === 0) return false;
return true;
}
function sieveOfEratosthenes(limit) {
const sieve = new Array(limit + 1).fill(true);
sieve[0] = sieve[1] = false;
for (let i = 2; i * i <= limit; i++) {
if (sieve[i]) for (let j = i * i; j <= limit; j += i) sieve[j] = false;
}
return sieve.map((v, i) => v ? i : -1).filter(v => v > 0);
}
function matMul(A, B, n) {
const C = Array.from({length: n}, () => new Array(n).fill(0));
for (let i = 0; i < n; i++)
for (let k = 0; k < n; k++)
for (let j = 0; j < n; j++)
C[i][j] += A[i][k] * B[k][j];
return C;
}
function makeMatrix(n, seed) {
const M = [];
for (let i = 0; i < n; i++) {
const row = [];
for (let j = 0; j < n; j++) row.push(((i * n + j + seed) % 17) * 0.1 + 1);
M.push(row);
}
return M;
}
function bubbleSort(arr) {
const a = [...arr];
for (let i = 0; i < a.length; i++)
for (let j = 0; j < a.length - i - 1; j++)
if (a[j] > a[j+1]) { let t = a[j]; a[j] = a[j+1]; a[j+1] = t; }
return a;
}
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const L = mergeSort(arr.slice(0, mid));
const R = mergeSort(arr.slice(mid));
const res = [];
let i = 0, j = 0;
while (i < L.length && j < R.length)
res.push(L[i] <= R[j] ? L[i++] : R[j++]);
return res.concat(L.slice(i)).concat(R.slice(j));
}
function lcg(seed) {
// Linear Congruential Generator for pseudo-random
return ((seed * 1664525 + 1013904223) & 0xffffffff) >>> 0;
}
function generateArray(size, seed) {
const arr = [];
let s = seed;
for (let i = 0; i < size; i++) { s = lcg(s); arr.push(s % 10000); }
return arr;
}
function polyEval(coeffs, x) {
let result = 0, power = 1;
for (const c of coeffs) { result += c * power; power *= x; }
return result;
}
function computeHash(str) {
let hash = 5381;
for (let i = 0; i < str.length; i++) hash = ((hash << 5) + hash + str.charCodeAt(i)) & 0xffffffff;
return hash >>> 0;
}
function runRLE(data) {
// Run-length encoding
if (!data.length) return [];
const out = [];
let cur = data[0], cnt = 1;
for (let i = 1; i < data.length; i++) {
if (data[i] === cur) cnt++;
else { out.push([cur, cnt]); cur = data[i]; cnt = 1; }
}
out.push([cur, cnt]);
return out;
}
// Random delay 200ms1500ms
const delay = 200 + (lcg(Date.now() & 0xffff) % 1300);
await sleep(delay);
// Phase 1: Sieve primes up to 2000
const primes = sieveOfEratosthenes(2000);
await sleep(50 + (lcg(primes.length) % 200));
// Phase 2: Fibonacci batch
const fibs = [];
for (let i = 20; i <= 50; i += 5) fibs.push({ n: i, val: fib(i) });
await sleep(30 + (lcg(fibs.length * 7) % 150));
// Phase 3: Matrix multiply 20×20
const A = makeMatrix(20, 3);
const B = makeMatrix(20, 7);
const C = matMul(A, B, 20);
const matSum = C.reduce((s, row) => s + row.reduce((a, b) => a + b, 0), 0);
await sleep(20 + (lcg(Math.floor(matSum) & 0xffff) % 100));
// Phase 4: Sort 800 elements two ways
const arr800 = generateArray(800, 42);
const bSorted = bubbleSort(arr800.slice(0, 200));
const mSorted = mergeSort(arr800);
await sleep(10 + (lcg(bSorted[0]) % 80));
// Phase 5: Polynomial evaluation
const coeffs = [1, -3, 2, 5, -1, 4, -2, 1, 3, -1, 2, 1, -3, 2, 5, -1];
const polyResults = [];
for (let x = -5; x <= 5; x += 0.5) polyResults.push(polyEval(coeffs, x));
await sleep(10 + (lcg(polyResults.length * 3) % 60));
// Phase 6: Hash chain
let h = computeHash("bench-node-start");
const hashChain = [h];
for (let i = 0; i < 500; i++) { h = computeHash(String(h)); hashChain.push(h); }
// Phase 7: RLE on prime indicators
const indicators = Array.from({length: 500}, (_, i) => isPrime(i) ? 1 : 0);
const rle = runRLE(indicators);
await sleep(10 + (lcg(hashChain[hashChain.length - 1] & 0xffff) % 50));
return {
body: JSON.stringify({
language: "nodejs",
delay_ms: delay,
prime_count: primes.length,
prime_sum: primes.reduce((a, b) => a + b, 0),
fibs: fibs,
mat_sum: matSum.toFixed(4),
sort_check: mSorted[0] <= mSorted[mSorted.length - 1],
poly_max: Math.max(...polyResults).toFixed(4),
hash_final: hashChain[hashChain.length - 1],
rle_segments: rle.length,
})
};
};
"""
# ── PHP ───────────────────────────────────────────────────────────────────────
PHP_CODE = r"""<?php
function handler($context) {
// ~10KB CPU work + random delays
$startTime = microtime(true);
// LCG pseudo-random
function lcg_rand($seed) {
return (($seed * 1664525 + 1013904223) & 0x7fffffff);
}
function is_prime($n) {
if ($n < 2) return false;
if ($n === 2) return true;
if ($n % 2 === 0) return false;
for ($i = 3; $i * $i <= $n; $i += 2) if ($n % $i === 0) return false;
return true;
}
function sieve($limit) {
$s = array_fill(0, $limit + 1, true);
$s[0] = $s[1] = false;
for ($i = 2; $i * $i <= $limit; $i++)
if ($s[$i]) for ($j = $i * $i; $j <= $limit; $j += $i) $s[$j] = false;
$primes = [];
for ($i = 2; $i <= $limit; $i++) if ($s[$i]) $primes[] = $i;
return $primes;
}
function mat_mul($A, $B, $n) {
$C = array_fill(0, $n, array_fill(0, $n, 0.0));
for ($i = 0; $i < $n; $i++)
for ($k = 0; $k < $n; $k++)
for ($j = 0; $j < $n; $j++)
$C[$i][$j] += $A[$i][$k] * $B[$k][$j];
return $C;
}
function make_matrix($n, $seed) {
$M = [];
for ($i = 0; $i < $n; $i++) {
$row = [];
for ($j = 0; $j < $n; $j++) $row[] = (($i * $n + $j + $seed) % 17) * 0.1 + 1.0;
$M[] = $row;
}
return $M;
}
function fib($n) {
if ($n <= 1) return $n;
$a = 0; $b = 1;
for ($i = 2; $i <= $n; $i++) { $t = $a + $b; $a = $b; $b = $t; }
return $b;
}
function insertion_sort($arr) {
$n = count($arr);
for ($i = 1; $i < $n; $i++) {
$key = $arr[$i]; $j = $i - 1;
while ($j >= 0 && $arr[$j] > $key) { $arr[$j + 1] = $arr[$j]; $j--; }
$arr[$j + 1] = $key;
}
return $arr;
}
function poly_eval($coeffs, $x) {
$result = 0.0; $power = 1.0;
foreach ($coeffs as $c) { $result += $c * $power; $power *= $x; }
return $result;
}
function djb2($str) {
$hash = 5381;
for ($i = 0; $i < strlen($str); $i++) $hash = (($hash << 5) + $hash + ord($str[$i])) & 0x7fffffff;
return $hash;
}
// Random delay 300ms-1200ms via usleep
$seed = (int)(microtime(true) * 1000) & 0xffff;
$delay_us = (300 + lcg_rand($seed) % 900) * 1000;
usleep($delay_us);
// Phase 1: Sieve primes up to 2000
$primes = sieve(2000);
$prime_sum = array_sum($primes);
// Phase 2: Fibonacci batch
$fibs = [];
for ($i = 20; $i <= 50; $i += 5) $fibs[$i] = fib($i);
usleep(30000 + lcg_rand(count($fibs)*7) % 100000);
// Phase 3: Matrix 20x20
$A = make_matrix(20, 5);
$B = make_matrix(20, 9);
$C = mat_mul($A, $B, 20);
$mat_sum = 0.0;
foreach ($C as $row) foreach ($row as $v) $mat_sum += $v;
usleep(20000 + lcg_rand((int)$mat_sum & 0xffff) % 80000);
// Phase 4: Insertion sort 300 elements
$arr = [];
$s2 = 99;
for ($i = 0; $i < 300; $i++) { $s2 = lcg_rand($s2); $arr[] = $s2 % 10000; }
$sorted = insertion_sort($arr);
usleep(10000 + lcg_rand($sorted[0]) % 60000);
// Phase 5: Polynomial evaluation
$coeffs = [1, -3, 2, 5, -1, 4, -2, 1, 3, -1, 2, 1, -3, 2, 5, -1];
$poly_max = -1e18;
for ($x = -5.0; $x <= 5.0; $x += 0.5) {
$v = poly_eval($coeffs, $x);
if ($v > $poly_max) $poly_max = $v;
}
usleep(10000 + lcg_rand(count($primes)) % 50000);
// Phase 6: Hash chain 500 iterations
$h = djb2("bench-php-start");
$chain = [$h];
for ($i = 0; $i < 500; $i++) { $h = djb2((string)$h); $chain[] = $h; }
// Phase 7: Count twin primes
$twins = 0;
for ($i = 0; $i < count($primes) - 1; $i++)
if ($primes[$i + 1] - $primes[$i] === 2) $twins++;
usleep(10000 + lcg_rand(end($chain)) % 40000);
$elapsed = round((microtime(true) - $startTime) * 1000);
$context["response"]->getBody()->write(json_encode([
"language" => "php",
"delay_ms" => (int)($delay_us / 1000),
"elapsed_ms" => $elapsed,
"prime_count" => count($primes),
"prime_sum" => $prime_sum,
"fib45" => $fibs[45],
"mat_sum" => round($mat_sum, 4),
"sort_ok" => $sorted[0] <= $sorted[count($sorted)-1],
"poly_max" => round($poly_max, 4),
"hash_final" => end($chain),
"twin_primes" => $twins,
]));
}
"""
# ── Ruby ──────────────────────────────────────────────────────────────────────
RUBY_CODE = r"""def handler
require 'json'
start_time = Time.now
# LCG pseudo-random
lcg = ->(s) { ((s * 1664525 + 1013904223) & 0x7fffffff) }
is_prime = ->(n) {
return false if n < 2
return true if n == 2
return false if n.even?
d = 3; while d * d <= n; return false if n % d == 0; d += 2; end
true
}
sieve = ->(limit) {
s = Array.new(limit + 1, true); s[0] = s[1] = false
i = 2; while i * i <= limit
if s[i]; j = i * i; while j <= limit; s[j] = false; j += i; end; end
i += 1
end
(2..limit).select { |k| s[k] }
}
mat_mul = ->(a, b, n) {
c = Array.new(n) { Array.new(n, 0.0) }
n.times { |i| n.times { |k| n.times { |j| c[i][j] += a[i][k] * b[k][j] } } }
c
}
make_matrix = ->(n, seed) {
Array.new(n) { |i| Array.new(n) { |j| ((i * n + j + seed) % 17) * 0.1 + 1.0 } }
}
fib = ->(n) {
return n if n <= 1
a, b = 0, 1; (n - 1).times { a, b = b, a + b }; b
}
shell_sort = ->(arr) {
a = arr.dup; gap = a.length / 2
while gap > 0
(gap...a.length).each { |i| tmp = a[i]; j = i; while j >= gap && a[j-gap] > tmp; a[j] = a[j-gap]; j -= gap; end; a[j] = tmp }
gap /= 2
end
a
}
poly_eval = ->(coeffs, x) {
result = 0.0; power = 1.0
coeffs.each { |c| result += c * power; power *= x }
result
}
djb2 = ->(str) {
h = 5381; str.each_byte { |b| h = ((h << 5) + h + b) & 0x7fffffff }; h
}
collatz = ->(n) { steps = 0; while n != 1; n = n.even? ? n / 2 : 3 * n + 1; steps += 1; end; steps }
# Random delay 250ms-1600ms
seed = (Time.now.to_f * 1000).to_i & 0xffff
delay_ms = 250 + lcg.(seed) % 1350
sleep(delay_ms / 1000.0)
# Phase 1: Sieve
primes = sieve.(2000)
prime_sum = primes.sum
sleep(0.05 + (lcg.(primes.length) % 200) / 1000.0)
# Phase 2: Fibonacci batch
fibs = (20..50).step(5).map { |n| [n, fib.(n)] }.to_h
sleep(0.03 + (lcg.(fibs.length * 7) % 150) / 1000.0)
# Phase 3: Matrix 20x20
a_mat = make_matrix.(20, 4)
b_mat = make_matrix.(20, 8)
c_mat = mat_mul.(a_mat, b_mat, 20)
mat_sum = c_mat.flatten.sum
sleep(0.02 + (lcg.(mat_sum.to_i & 0xffff) % 100) / 1000.0)
# Phase 4: Shell sort 500 elements
s2 = 77
arr = Array.new(500) { s2 = lcg.(s2); s2 % 10000 }
sorted = shell_sort.(arr)
sleep(0.01 + (lcg.(sorted.first) % 80) / 1000.0)
# Phase 5: Polynomial
coeffs = [1, -3, 2, 5, -1, 4, -2, 1, 3, -1, 2, 1, -3, 2, 5, -1]
poly_max = (-5.0..5.0).step(0.5).map { |x| poly_eval.(coeffs, x) }.max
sleep(0.01 + (lcg.(primes.length) % 60) / 1000.0)
# Phase 6: Hash chain
h = djb2.("bench-ruby-start")
chain = [h]
500.times { h = djb2.(h.to_s); chain << h }
# Phase 7: Collatz max steps for 1..200
collatz_max = (1..200).map { |n| collatz.(n) }.max
sleep(0.01 + (lcg.(chain.last & 0xffff) % 50) / 1000.0)
elapsed_ms = ((Time.now - start_time) * 1000).round
{
language: "ruby",
delay_ms: delay_ms,
elapsed_ms: elapsed_ms,
prime_count: primes.size,
prime_sum: prime_sum,
fib45: fibs[45],
mat_sum: mat_sum.round(4),
sort_ok: sorted.first <= sorted.last,
poly_max: poly_max.round(4),
hash_final: chain.last,
collatz_max: collatz_max,
}.to_json
end
"""
# ── Perl ──────────────────────────────────────────────────────────────────────
PERL_CODE = r"""sub {
use Time::HiRes qw(time usleep);
use POSIX qw(floor);
my $start = time();
sub lcg_r { return (($_[0] * 1664525 + 1013904223) & 0x7fffffff); }
sub is_prime_p {
my $n = shift; return 0 if $n < 2; return 1 if $n == 2;
return 0 if $n % 2 == 0;
my $i = 3; while ($i * $i <= $n) { return 0 if $n % $i == 0; $i += 2; } return 1;
}
sub sieve_p {
my $lim = shift;
my @s = (1) x ($lim + 1); $s[0] = $s[1] = 0;
for (my $i = 2; $i * $i <= $lim; $i++) {
if ($s[$i]) { for (my $j = $i*$i; $j <= $lim; $j += $i) { $s[$j] = 0; } }
}
return grep { $s[$_] } 2..$lim;
}
sub fib_p {
my $n = shift; return $n if $n <= 1;
my ($a, $b) = (0, 1);
for (my $i = 2; $i <= $n; $i++) { ($a, $b) = ($b, $a + $b); }
return $b;
}
sub mat_mul_p {
my ($A, $B, $n) = @_;
my @C = map { [(0) x $n] } 0..$n-1;
for my $i (0..$n-1) { for my $k (0..$n-1) { for my $j (0..$n-1) {
$C[$i][$j] += $A->[$i][$k] * $B->[$k][$j];
}}}
return @C;
}
sub make_mat_p {
my ($n, $seed) = @_;
return map { my $i = $_; [ map { (($i*$n+$_+$seed)%17)*0.1+1.0 } 0..$n-1 ] } 0..$n-1;
}
sub djb2_p {
my $str = shift; my $h = 5381;
for my $c (split //, $str) { $h = (($h<<5)+$h+ord($c)) & 0x7fffffff; }
return $h;
}
sub selection_sort_p {
my @a = @_; my $n = scalar @a;
for my $i (0..$n-2) {
my $min = $i;
for my $j ($i+1..$n-1) { $min = $j if $a[$j] < $a[$min]; }
@a[$i, $min] = @a[$min, $i] if $min != $i;
}
return @a;
}
sub poly_eval_p {
my ($coeffs, $x) = @_; my ($r, $p) = (0.0, 1.0);
for my $c (@$coeffs) { $r += $c * $p; $p *= $x; }
return $r;
}
sub collatz_p {
my $n = shift; my $steps = 0;
while ($n != 1) { $n = ($n % 2 == 0) ? $n/2 : 3*$n+1; $steps++; }
return $steps;
}
# Random delay 300ms-1500ms
my $seed = int(time() * 1000) & 0xffff;
my $delay_us = (300 + lcg_r($seed) % 1200) * 1000;
usleep($delay_us);
# Phase 1: Sieve
my @primes = sieve_p(2000);
my $prime_sum = 0; $prime_sum += $_ for @primes;
usleep(50000 + lcg_r(scalar @primes) % 200000);
# Phase 2: Fibonacci
my %fibs = map { $_ => fib_p($_) } grep { $_ % 5 == 0 } 20..50;
usleep(30000 + lcg_r(scalar keys %fibs) % 150000);
# Phase 3: Matrix 15x15
my @A = make_mat_p(15, 6);
my @B = make_mat_p(15, 11);
my @C = mat_mul_p(\@A, \@B, 15);
my $mat_sum = 0.0;
for my $row (@C) { $mat_sum += $_ for @$row; }
usleep(20000 + lcg_r(int($mat_sum) & 0xffff) % 100000);
# Phase 4: Selection sort 250 elements
my $s2 = 55; my @arr;
for (1..250) { $s2 = lcg_r($s2); push @arr, $s2 % 10000; }
my @sorted = selection_sort_p(@arr);
usleep(10000 + lcg_r($sorted[0]) % 80000);
# Phase 5: Polynomial
my @coeffs = (1, -3, 2, 5, -1, 4, -2, 1, 3, -1, 2, 1, -3, 2, 5, -1);
my $poly_max = -1e18;
for (my $x = -5.0; $x <= 5.0; $x += 0.5) {
my $v = poly_eval_p(\@coeffs, $x); $poly_max = $v if $v > $poly_max;
}
usleep(10000 + lcg_r(scalar @primes) % 60000);
# Phase 6: Hash chain
my $h = djb2_p("bench-perl-start");
my @chain = ($h);
for (1..500) { $h = djb2_p("$h"); push @chain, $h; }
# Phase 7: Collatz
my $cmax = 0;
for my $n (1..200) { my $s = collatz_p($n); $cmax = $s if $s > $cmax; }
usleep(10000 + lcg_r($chain[-1] & 0xffff) % 50000);
my $elapsed_ms = int((time() - $start) * 1000);
return sprintf('{"language":"perl","delay_ms":%d,"elapsed_ms":%d,"prime_count":%d,"prime_sum":%d,"fib45":%d,"mat_sum":%.4f,"sort_ok":%s,"poly_max":%.4f,"hash_final":%d,"collatz_max":%d}',
int($delay_us/1000), $elapsed_ms, scalar @primes, $prime_sum, $fibs{45},
$mat_sum, ($sorted[0] <= $sorted[-1] ? "true" : "false"),
$poly_max, $chain[-1], $cmax);
}
"""
# ── Go ────────────────────────────────────────────────────────────────────────
GO_CODE = r"""package main
import (
"encoding/json"
"fmt"
"math"
"math/rand"
"net/http"
"sort"
"strings"
"time"
)
func sieveGo(limit int) []int {
s := make([]bool, limit+1)
for i := range s { s[i] = true }
s[0], s[1] = false, false
for i := 2; i*i <= limit; i++ {
if s[i] { for j := i * i; j <= limit; j += i { s[j] = false } }
}
primes := []int{}
for i := 2; i <= limit; i++ { if s[i] { primes = append(primes, i) } }
return primes
}
func fibGo(n int) int64 {
if n <= 1 { return int64(n) }
a, b := int64(0), int64(1)
for i := 2; i <= n; i++ { a, b = b, a+b }
return b
}
func matMulGo(a, b [20][20]float64) [20][20]float64 {
var c [20][20]float64
for i := 0; i < 20; i++ {
for k := 0; k < 20; k++ {
for j := 0; j < 20; j++ { c[i][j] += a[i][k] * b[k][j] }
}
}
return c
}
func makeMatGo(seed float64) [20][20]float64 {
var m [20][20]float64
for i := 0; i < 20; i++ {
for j := 0; j < 20; j++ {
m[i][j] = math.Mod(float64(i*20+j)+seed, 17)*0.1 + 1.0
}
}
return m
}
func shellSortGo(arr []int) []int {
a := make([]int, len(arr)); copy(a, arr)
for gap := len(a) / 2; gap > 0; gap /= 2 {
for i := gap; i < len(a); i++ {
tmp := a[i]; j := i
for j >= gap && a[j-gap] > tmp { a[j] = a[j-gap]; j -= gap }
a[j] = tmp
}
}
return a
}
func quickSortGo(arr []int) []int {
a := make([]int, len(arr)); copy(a, arr)
sort.Ints(a)
return a
}
func polyEvalGo(coeffs []float64, x float64) float64 {
result, power := 0.0, 1.0
for _, c := range coeffs { result += c * power; power *= x }
return result
}
func djb2Go(s string) uint32 {
h := uint32(5381)
for _, c := range s { h = ((h << 5) + h + uint32(c)) & 0x7fffffff }
return h
}
func fnv1aGo(s string) uint32 {
h := uint32(2166136261)
for _, c := range []byte(s) { h ^= uint32(c); h *= 16777619 }
return h
}
func collatzGo(n int) int {
steps := 0
for n != 1 {
if n%2 == 0 { n /= 2 } else { n = 3*n + 1 }
steps++
}
return steps
}
func isPrimeGo(n int) bool {
if n < 2 { return false }
if n == 2 { return true }
if n%2 == 0 { return false }
for d := 3; d*d <= n; d += 2 { if n%d == 0 { return false } }
return true
}
func gcdGo(a, b int) int {
for b != 0 { a, b = b, a%b }
return a
}
func lcmGo(a, b int) int { return a / gcdGo(a, b) * b }
// Горнер для вычисления полинома
func hornerEval(coeffs []float64, x float64) float64 {
result := 0.0
for i := len(coeffs) - 1; i >= 0; i-- { result = result*x + coeffs[i] }
return result
}
// Решето Сундарама
func sundaramSieve(n int) []int {
limit := (n - 2) / 2
s := make([]bool, limit+1)
for i := 1; i <= limit; i++ {
for j := i; i+j+2*i*j <= limit; j++ { s[i+j+2*i*j] = true }
}
primes := []int{2}
for i := 1; i <= limit; i++ { if !s[i] { primes = append(primes, 2*i+1) } }
return primes
}
// Простые числа через Miller-Rabin (детерминированный для малых n)
func millerRabinGo(n int) bool {
if n < 2 { return false }
if n == 2 || n == 3 || n == 5 || n == 7 { return true }
if n%2 == 0 { return false }
d, r := n-1, 0
for d%2 == 0 { d /= 2; r++ }
witnesses := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}
for _, a := range witnesses {
if a >= n { continue }
x := modPowGo(a, d, n)
if x == 1 || x == n-1 { continue }
cont := false
for _ = range make([]struct{}, r-1) {
x = modPowGo(x, 2, n)
if x == n-1 { cont = true; break }
}
if !cont { return false }
}
return true
}
func modPowGo(base, exp, mod int) int {
result := 1; base %= mod
for exp > 0 {
if exp%2 == 1 { result = result * base % mod }
exp /= 2; base = base * base % mod
}
return result
}
// Числа Люка
func lucasGo(n int) int64 {
if n == 0 { return 2 }
if n == 1 { return 1 }
a, b := int64(2), int64(1)
for i := 2; i <= n; i++ { a, b = b, a+b }
return b
}
// Цифровая сумма
func digitSumGo(n int) int {
s := 0
for n > 0 { s += n % 10; n /= 10 }
return s
}
func Handler(w http.ResponseWriter, r *http.Request) {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
// Random delay 300ms-1800ms
delayMs := 300 + rng.Intn(1500)
time.Sleep(time.Duration(delayMs) * time.Millisecond)
// Phase 1: Sieve of Eratosthenes up to 3000
primes := sieveGo(3000)
primeSum := 0
for _, p := range primes { primeSum += p }
time.Sleep(time.Duration(50+rng.Intn(200)) * time.Millisecond)
// Phase 2: Sundaram sieve cross-check
primes2 := sundaramSieve(3000)
_ = primes2
time.Sleep(time.Duration(30+rng.Intn(150)) * time.Millisecond)
// Phase 3: Miller-Rabin for 1000..1200
mrCount := 0
for n := 1000; n <= 1200; n++ { if millerRabinGo(n) { mrCount++ } }
time.Sleep(time.Duration(20+rng.Intn(100)) * time.Millisecond)
// Phase 4: Fibonacci + Lucas + digit sums
type entry struct{ N int; Fib, Lucas int64; DigSum int }
entries := []entry{}
for n := 20; n <= 60; n += 5 {
f := fibGo(n); l := lucasGo(n)
entries = append(entries, entry{n, f, l, digitSumGo(int(f % 1000000))})
}
time.Sleep(time.Duration(30+rng.Intn(150)) * time.Millisecond)
// Phase 5: Matrix multiply 20x20
A := makeMatGo(3.0); B := makeMatGo(7.0)
C := matMulGo(A, B)
matSum := 0.0
for _, row := range C { for _, v := range row { matSum += v } }
time.Sleep(time.Duration(20+rng.Intn(100)) * time.Millisecond)
// Phase 6: Shell sort + stdlib sort 800 elements, compare
arr := make([]int, 800)
for i := range arr { arr[i] = rng.Intn(10000) }
shellSorted := shellSortGo(arr)
quickSorted := quickSortGo(arr)
sortMatch := true
for i := range shellSorted { if shellSorted[i] != quickSorted[i] { sortMatch = false; break } }
time.Sleep(time.Duration(10+rng.Intn(80)) * time.Millisecond)
// Phase 7: Polynomial evaluation (Horner vs direct)
coeffs := []float64{1, -3, 2, 5, -1, 4, -2, 1, 3, -1, 2, 1, -3, 2, 5, -1, 3, -2, 1, 4}
polyMax, hornerMax := math.Inf(-1), math.Inf(-1)
for i := -80; i <= 80; i++ {
x := float64(i) * 0.1
if v := polyEvalGo(coeffs, x); v > polyMax { polyMax = v }
if v := hornerEval(coeffs, x); v > hornerMax { hornerMax = v }
}
time.Sleep(time.Duration(10+rng.Intn(60)) * time.Millisecond)
// Phase 8: DJB2 + FNV1a hash chains 500 iterations
hDJB := djb2Go("bench-go-start")
hFNV := fnv1aGo("bench-go-start")
for i := 0; i < 500; i++ {
hDJB = djb2Go(fmt.Sprintf("%d", hDJB))
hFNV = fnv1aGo(fmt.Sprintf("%d", hFNV))
}
time.Sleep(time.Duration(10+rng.Intn(50)) * time.Millisecond)
// Phase 9: Collatz max steps for 1..500
collatzMax, collatzN := 0, 0
for n := 1; n <= 500; n++ {
if s := collatzGo(n); s > collatzMax { collatzMax = s; collatzN = n }
}
// Phase 10: GCD/LCM table for first 20 primes
gcdSum, lcmMod := 0, 1
for i := 0; i < 20 && i < len(primes)-1; i++ {
gcdSum += gcdGo(primes[i], primes[i+1])
lcmMod = lcmGo(lcmMod, primes[i]) % 1000000007
}
time.Sleep(time.Duration(10+rng.Intn(40)) * time.Millisecond)
// Phase 11: Twin primes and cousin primes
twins, cousins := 0, 0
for i := 0; i < len(primes)-1; i++ {
diff := primes[i+1] - primes[i]
if diff == 2 { twins++ }
if diff == 4 { cousins++ }
}
// Phase 12: String operations — build prime list string and count digits
var sb strings.Builder
for i, p := range primes { if i >= 100 { break }; fmt.Fprintf(&sb, "%d,", p) }
primeStr := sb.String()
digitCount := 0
for _, c := range primeStr { if c >= '0' && c <= '9' { digitCount++ } }
result := map[string]interface{}{
"language": "go",
"delay_ms": delayMs,
"prime_count": len(primes),
"prime_sum": primeSum,
"mr_count": mrCount,
"fib55": entries[7].Fib,
"lucas55": entries[7].Lucas,
"mat_sum": math.Round(matSum*10000) / 10000,
"sort_match": sortMatch,
"poly_max": math.Round(polyMax*10000) / 10000,
"horner_max": math.Round(hornerMax*10000) / 10000,
"djb2_final": hDJB,
"fnv1a_final": hFNV,
"collatz_max": collatzMax,
"collatz_n": collatzN,
"twin_primes": twins,
"cousin_primes": cousins,
"gcd_sum": gcdSum,
"lcm_mod": lcmMod,
"digit_count": digitCount,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
}
"""
# ── Python ────────────────────────────────────────────────────────────────────
PYTHON_CODE = r"""import time
import math
import random
def sieve(limit):
s = [True] * (limit + 1); s[0] = s[1] = False
i = 2
while i * i <= limit:
if s[i]:
j = i * i
while j <= limit: s[j] = False; j += i
i += 1
return [i for i in range(2, limit+1) if s[i]]
def fib(n):
if n <= 1: return n
a, b = 0, 1
for _ in range(n - 1): a, b = b, a + b
return b
def mat_mul(A, B, n):
C = [[0.0]*n for _ in range(n)]
for i in range(n):
for k in range(n):
for j in range(n):
C[i][j] += A[i][k] * B[k][j]
return C
def make_matrix(n, seed):
return [[(((i*n+j+seed)%17)*0.1+1.0) for j in range(n)] for i in range(n)]
def shell_sort(arr):
a = arr[:]
gap = len(a) // 2
while gap > 0:
for i in range(gap, len(a)):
tmp = a[i]; j = i
while j >= gap and a[j-gap] > tmp: a[j] = a[j-gap]; j -= gap
a[j] = tmp
gap //= 2
return a
def poly_eval(coeffs, x):
result, power = 0.0, 1.0
for c in coeffs: result += c * power; power *= x
return result
def djb2(s):
h = 5381
for c in s: h = ((h << 5) + h + ord(c)) & 0x7fffffff
return h
def collatz(n):
steps = 0
while n != 1: n = n // 2 if n % 2 == 0 else 3 * n + 1; steps += 1
return steps
def lcg(s): return ((s * 1664525 + 1013904223) & 0x7fffffff)
def main():
start = time.time()
# Random delay 250ms-1500ms
seed = int(start * 1000) & 0xffff
delay_ms = 250 + lcg(seed) % 1250
time.sleep(delay_ms / 1000.0)
# Phase 1: Sieve primes up to 2000
primes = sieve(2000)
prime_sum = sum(primes)
time.sleep(0.05 + (lcg(len(primes)) % 200) / 1000.0)
# Phase 2: Fibonacci batch
fibs = {n: fib(n) for n in range(20, 51, 5)}
time.sleep(0.03 + (lcg(len(fibs) * 7) % 150) / 1000.0)
# Phase 3: Matrix 20x20
A = make_matrix(20, 2)
B = make_matrix(20, 6)
C = mat_mul(A, B, 20)
mat_sum = sum(v for row in C for v in row)
time.sleep(0.02 + (lcg(int(mat_sum) & 0xffff) % 100) / 1000.0)
# Phase 4: Shell sort 500 elements
s2 = 33
arr = []
for _ in range(500): s2 = lcg(s2); arr.append(s2 % 10000)
sorted_arr = shell_sort(arr)
time.sleep(0.01 + (lcg(sorted_arr[0]) % 80) / 1000.0)
# Phase 5: Polynomial evaluation
coeffs = [1, -3, 2, 5, -1, 4, -2, 1, 3, -1, 2, 1, -3, 2, 5, -1]
poly_vals = [poly_eval(coeffs, x * 0.25) for x in range(-20, 21)]
poly_max = max(poly_vals)
time.sleep(0.01 + (lcg(len(primes)) % 60) / 1000.0)
# Phase 6: Hash chain 500 iterations
h = djb2("bench-python-start")
chain = [h]
for _ in range(500): h = djb2(str(h)); chain.append(h)
# Phase 7: Collatz max steps for 1..300
collatz_max = max(collatz(n) for n in range(1, 301))
time.sleep(0.01 + (lcg(chain[-1] & 0xffff) % 50) / 1000.0)
# Phase 8: Sum of squares (1..200)
sq_sum = sum(i * i for i in range(1, 201))
# Phase 9: GCD / LCM chain on primes
def gcd(a, b):
while b: a, b = b, a % b
return a
gcds = [gcd(primes[i], primes[i+1]) for i in range(min(50, len(primes)-1))]
elapsed_ms = round((time.time() - start) * 1000)
return {
"language": "python",
"delay_ms": delay_ms,
"elapsed_ms": elapsed_ms,
"prime_count": len(primes),
"prime_sum": prime_sum,
"fib45": fibs[45],
"mat_sum": round(mat_sum, 4),
"sort_ok": sorted_arr[0] <= sorted_arr[-1],
"poly_max": round(poly_max, 4),
"hash_final": chain[-1],
"collatz_max": collatz_max,
"sq_sum": sq_sum,
"gcd_sum": sum(gcds),
}
"""
functions = [
("bench-node", "nodejs", NODE_CODE),
("bench-php", "php", PHP_CODE),
("bench-ruby", "ruby", RUBY_CODE),
("bench-perl", "perl", PERL_CODE),
("bench-go", "go", GO_CODE),
("bench-python", "python", PYTHON_CODE),
]
print("=== Удаляем старые bench-функции ===")
for name, _, _ in functions:
result = subprocess.run(
["curl", "-s", "-X", "DELETE", f"{BASE}/functions/{name}",
"-H", f"X-Test-Sub: {SUB}"],
capture_output=True, text=True
)
print(f" DELETE {name}: {result.stdout.strip()[:80]}")
print("\n=== Создаём тяжёлые bench-функции (~10KB) ===")
for name, lang, code in functions:
payload = json.dumps({"name": name, "language": lang, "code": code, "ttl": "2h"})
size_kb = len(code) / 1024
result = subprocess.run(
["curl", "-s", "-X", "POST", f"{BASE}/functions",
"-H", f"X-Test-Sub: {SUB}", "-H", "Content-Type: application/json",
"-d", payload],
capture_output=True, text=True
)
try:
resp = json.loads(result.stdout)
route = resp.get("route", "?")
print(f" {name} ({size_kb:.1f}KB): {route}")
except Exception as e:
print(f" {name}: PARSE ERROR {result.stdout[:150]}")