Velocicode 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- velocicode/__init__.py +0 -0
- velocicode/benchmarks/fibonacci/cpp/main.cpp +16 -0
- velocicode/benchmarks/fibonacci/go/main.go +25 -0
- velocicode/benchmarks/fibonacci/javascript/main.js +9 -0
- velocicode/benchmarks/fibonacci/python/main.py +12 -0
- velocicode/benchmarks/fibonacci/rust/main.rs +18 -0
- velocicode/benchmarks/matrix_mul/cpp/main.cpp +41 -0
- velocicode/benchmarks/matrix_mul/go/main.go +49 -0
- velocicode/benchmarks/matrix_mul/javascript/main.js +31 -0
- velocicode/benchmarks/matrix_mul/python/main.py +25 -0
- velocicode/benchmarks/matrix_mul/rust/main.rs +37 -0
- velocicode/benchmarks/primes/cpp/main.cpp +28 -0
- velocicode/benchmarks/primes/go/main.go +40 -0
- velocicode/benchmarks/primes/javascript/main.js +20 -0
- velocicode/benchmarks/primes/python/main.py +24 -0
- velocicode/benchmarks/primes/rust/main.rs +35 -0
- velocicode/benchmarks/quicksort/cpp/main.cpp +24 -0
- velocicode/benchmarks/quicksort/go/main.go +26 -0
- velocicode/benchmarks/quicksort/javascript/main.js +11 -0
- velocicode/benchmarks/quicksort/python/main.py +26 -0
- velocicode/benchmarks/quicksort/rust/main.rs +40 -0
- velocicode/config.yaml +16 -0
- velocicode/main.py +239 -0
- velocicode/report_generator.py +143 -0
- velocicode/reporter.py +79 -0
- velocicode/runner.py +65 -0
- velocicode/system_info.py +23 -0
- velocicode-0.5.0.dist-info/METADATA +92 -0
- velocicode-0.5.0.dist-info/RECORD +33 -0
- velocicode-0.5.0.dist-info/WHEEL +5 -0
- velocicode-0.5.0.dist-info/entry_points.txt +2 -0
- velocicode-0.5.0.dist-info/licenses/LICENSE +21 -0
- velocicode-0.5.0.dist-info/top_level.txt +1 -0
velocicode/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <cstdlib>
|
|
3
|
+
|
|
4
|
+
int fib(int n) {
|
|
5
|
+
if (n <= 1) return n;
|
|
6
|
+
return fib(n - 1) + fib(n - 2);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
int main(int argc, char* argv[]) {
|
|
10
|
+
int n = 35;
|
|
11
|
+
if (argc > 1) {
|
|
12
|
+
n = std::atoi(argv[1]);
|
|
13
|
+
}
|
|
14
|
+
std::cout << fib(n) << std::endl;
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"os"
|
|
6
|
+
"strconv"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
func fib(n int) int {
|
|
10
|
+
if n <= 1 {
|
|
11
|
+
return n
|
|
12
|
+
}
|
|
13
|
+
return fib(n-1) + fib(n-2)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func main() {
|
|
17
|
+
n := 35
|
|
18
|
+
if len(os.Args) > 1 {
|
|
19
|
+
val, err := strconv.Atoi(os.Args[1])
|
|
20
|
+
if err == nil {
|
|
21
|
+
n = val
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
fmt.Println(fib(n))
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
use std::env;
|
|
2
|
+
|
|
3
|
+
fn fib(n: u32) -> u32 {
|
|
4
|
+
if n <= 1 {
|
|
5
|
+
return n;
|
|
6
|
+
}
|
|
7
|
+
fib(n - 1) + fib(n - 2)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
fn main() {
|
|
11
|
+
let args: Vec<String> = env::args().collect();
|
|
12
|
+
let n = if args.len() > 1 {
|
|
13
|
+
args[1].parse().unwrap_or(35)
|
|
14
|
+
} else {
|
|
15
|
+
35
|
|
16
|
+
};
|
|
17
|
+
println!("{}", fib(n));
|
|
18
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <vector>
|
|
3
|
+
#include <cstdlib>
|
|
4
|
+
#include <random>
|
|
5
|
+
|
|
6
|
+
using namespace std;
|
|
7
|
+
|
|
8
|
+
vector<vector<double>> generate_matrix(int n) {
|
|
9
|
+
vector<vector<double>> m(n, vector<double>(n));
|
|
10
|
+
random_device rd;
|
|
11
|
+
mt19937 gen(rd());
|
|
12
|
+
uniform_real_distribution<> dis(0.0, 1.0);
|
|
13
|
+
for(int i=0; i<n; ++i)
|
|
14
|
+
for(int j=0; j<n; ++j)
|
|
15
|
+
m[i][j] = dis(gen);
|
|
16
|
+
return m;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
vector<vector<double>> mat_mul(const vector<vector<double>>& A, const vector<vector<double>>& B, int n) {
|
|
20
|
+
vector<vector<double>> C(n, vector<double>(n, 0.0));
|
|
21
|
+
for (int i = 0; i < n; ++i) {
|
|
22
|
+
for (int k = 0; k < n; ++k) {
|
|
23
|
+
for (int j = 0; j < n; ++j) {
|
|
24
|
+
C[i][j] += A[i][k] * B[k][j];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return C;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
int main(int argc, char* argv[]) {
|
|
32
|
+
int n = 200;
|
|
33
|
+
if (argc > 1) n = atoi(argv[1]);
|
|
34
|
+
|
|
35
|
+
auto A = generate_matrix(n);
|
|
36
|
+
auto B = generate_matrix(n);
|
|
37
|
+
auto C = mat_mul(A, B, n);
|
|
38
|
+
|
|
39
|
+
cout << C[0][0] << endl;
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"math/rand"
|
|
6
|
+
"os"
|
|
7
|
+
"strconv"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
func generateMatrix(n int) [][]float64 {
|
|
11
|
+
m := make([][]float64, n)
|
|
12
|
+
for i := range m {
|
|
13
|
+
m[i] = make([]float64, n)
|
|
14
|
+
for j := range m[i] {
|
|
15
|
+
m[i][j] = rand.Float64()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return m
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func matMul(a, b [][]float64, n int) [][]float64 {
|
|
22
|
+
c := make([][]float64, n)
|
|
23
|
+
for i := range c {
|
|
24
|
+
c[i] = make([]float64, n)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for i := 0; i < n; i++ {
|
|
28
|
+
for k := 0; k < n; k++ {
|
|
29
|
+
for j := 0; j < n; j++ {
|
|
30
|
+
c[i][j] += a[i][k] * b[k][j]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return c
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
func main() {
|
|
38
|
+
n := 200
|
|
39
|
+
if len(os.Args) > 1 {
|
|
40
|
+
if val, err := strconv.Atoi(os.Args[1]); err == nil {
|
|
41
|
+
n = val
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
a := generateMatrix(n)
|
|
46
|
+
b := generateMatrix(n)
|
|
47
|
+
c := matMul(a, b, n)
|
|
48
|
+
fmt.Println(c[0][0])
|
|
49
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function generateMatrix(n) {
|
|
2
|
+
const m = [];
|
|
3
|
+
for (let i = 0; i < n; i++) {
|
|
4
|
+
m[i] = [];
|
|
5
|
+
for (let j = 0; j < n; j++) {
|
|
6
|
+
m[i][j] = Math.random();
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return m;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function matMul(A, B, n) {
|
|
13
|
+
const C = [];
|
|
14
|
+
for (let i = 0; i < n; i++) {
|
|
15
|
+
C[i] = new Float64Array(n);
|
|
16
|
+
for (let k = 0; k < n; k++) {
|
|
17
|
+
for (let j = 0; j < n; j++) {
|
|
18
|
+
C[i][j] += A[i][k] * B[k][j];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return C;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const args = process.argv.slice(2);
|
|
26
|
+
const n = args.length > 0 ? parseInt(args[0]) : 200;
|
|
27
|
+
|
|
28
|
+
const A = generateMatrix(n);
|
|
29
|
+
const B = generateMatrix(n);
|
|
30
|
+
const C = matMul(A, B, n);
|
|
31
|
+
console.log(C[0][0]);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import random
|
|
3
|
+
|
|
4
|
+
def generate_matrix(n):
|
|
5
|
+
return [[random.random() for _ in range(n)] for _ in range(n)]
|
|
6
|
+
|
|
7
|
+
def mat_mul(A, B, n):
|
|
8
|
+
C = [[0] * n for _ in range(n)]
|
|
9
|
+
for i in range(n):
|
|
10
|
+
for j in range(n):
|
|
11
|
+
sum_val = 0
|
|
12
|
+
for k in range(n):
|
|
13
|
+
sum_val += A[i][k] * B[k][j]
|
|
14
|
+
C[i][j] = sum_val
|
|
15
|
+
return C
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
n = 200
|
|
19
|
+
if len(sys.argv) > 1:
|
|
20
|
+
n = int(sys.argv[1])
|
|
21
|
+
|
|
22
|
+
A = generate_matrix(n)
|
|
23
|
+
B = generate_matrix(n)
|
|
24
|
+
C = mat_mul(A, B, n)
|
|
25
|
+
print(C[0][0]) # prevent optimization
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
use std::env;
|
|
2
|
+
|
|
3
|
+
fn generate_matrix(n: usize) -> Vec<Vec<f64>> {
|
|
4
|
+
let mut m = vec![vec![0.0; n]; n];
|
|
5
|
+
for i in 0..n {
|
|
6
|
+
for j in 0..n {
|
|
7
|
+
m[i][j] = (i as f64 + j as f64) * 0.001; // Simple deterministic generation
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
m
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
fn mat_mul(a: &Vec<Vec<f64>>, b: &Vec<Vec<f64>>, n: usize) -> Vec<Vec<f64>> {
|
|
14
|
+
let mut c = vec![vec![0.0; n]; n];
|
|
15
|
+
for i in 0..n {
|
|
16
|
+
for k in 0..n {
|
|
17
|
+
for j in 0..n {
|
|
18
|
+
c[i][j] += a[i][k] * b[k][j];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
c
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fn main() {
|
|
26
|
+
let args: Vec<String> = env::args().collect();
|
|
27
|
+
let n = if args.len() > 1 {
|
|
28
|
+
args[1].parse().unwrap_or(200)
|
|
29
|
+
} else {
|
|
30
|
+
200
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let a = generate_matrix(n);
|
|
34
|
+
let b = generate_matrix(n);
|
|
35
|
+
let c = mat_mul(&a, &b, n);
|
|
36
|
+
println!("{}", c[0][0]);
|
|
37
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <vector>
|
|
3
|
+
#include <cstdlib>
|
|
4
|
+
|
|
5
|
+
using namespace std;
|
|
6
|
+
|
|
7
|
+
int sieve(int n) {
|
|
8
|
+
vector<bool> primes(n + 1, true);
|
|
9
|
+
for (int p = 2; p * p <= n; p++) {
|
|
10
|
+
if (primes[p] == true) {
|
|
11
|
+
for (int i = p * p; i <= n; i += p)
|
|
12
|
+
primes[i] = false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
int count = 0;
|
|
17
|
+
for (int p = 2; p <= n; p++)
|
|
18
|
+
if (primes[p]) count++;
|
|
19
|
+
return count;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
int main(int argc, char* argv[]) {
|
|
23
|
+
int n = 1000000;
|
|
24
|
+
if (argc > 1) n = atoi(argv[1]);
|
|
25
|
+
|
|
26
|
+
cout << sieve(n) << endl;
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"os"
|
|
6
|
+
"strconv"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
func sieve(n int) int {
|
|
10
|
+
primes := make([]bool, n+1)
|
|
11
|
+
for i := 0; i <= n; i++ {
|
|
12
|
+
primes[i] = true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
for p := 2; p*p <= n; p++ {
|
|
16
|
+
if primes[p] == true {
|
|
17
|
+
for i := p * p; i <= n; i += p {
|
|
18
|
+
primes[i] = false
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
count := 0
|
|
24
|
+
for p := 2; p <= n; p++ {
|
|
25
|
+
if primes[p] {
|
|
26
|
+
count++
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return count
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func main() {
|
|
33
|
+
n := 1000000
|
|
34
|
+
if len(os.Args) > 1 {
|
|
35
|
+
if val, err := strconv.Atoi(os.Args[1]); err == nil {
|
|
36
|
+
n = val
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
fmt.Println(sieve(n))
|
|
40
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function sieve(n) {
|
|
2
|
+
const primes = new Uint8Array(n + 1).fill(1);
|
|
3
|
+
|
|
4
|
+
for (let p = 2; p * p <= n; p++) {
|
|
5
|
+
if (primes[p] === 1) {
|
|
6
|
+
for (let i = p * p; i <= n; i += p)
|
|
7
|
+
primes[i] = 0;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let count = 0;
|
|
12
|
+
for (let p = 2; p <= n; p++)
|
|
13
|
+
if (primes[p] === 1) count++;
|
|
14
|
+
return count;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
const n = args.length > 0 ? parseInt(args[0]) : 1000000;
|
|
19
|
+
|
|
20
|
+
console.log(sieve(n));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def sieve(n):
|
|
4
|
+
primes = [True] * (n + 1)
|
|
5
|
+
p = 2
|
|
6
|
+
while (p * p <= n):
|
|
7
|
+
if (primes[p] == True):
|
|
8
|
+
for i in range(p * p, n + 1, p):
|
|
9
|
+
primes[i] = False
|
|
10
|
+
p += 1
|
|
11
|
+
|
|
12
|
+
# Count primes
|
|
13
|
+
count = 0
|
|
14
|
+
for p in range(2, n + 1):
|
|
15
|
+
if primes[p]:
|
|
16
|
+
count += 1
|
|
17
|
+
return count
|
|
18
|
+
|
|
19
|
+
if __name__ == "__main__":
|
|
20
|
+
n = 1000000
|
|
21
|
+
if len(sys.argv) > 1:
|
|
22
|
+
n = int(sys.argv[1])
|
|
23
|
+
|
|
24
|
+
print(sieve(n))
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
use std::env;
|
|
2
|
+
|
|
3
|
+
fn sieve(n: usize) -> i32 {
|
|
4
|
+
let mut primes = vec![true; n + 1];
|
|
5
|
+
let mut p = 2;
|
|
6
|
+
while p * p <= n {
|
|
7
|
+
if primes[p] {
|
|
8
|
+
let mut i = p * p;
|
|
9
|
+
while i <= n {
|
|
10
|
+
primes[i] = false;
|
|
11
|
+
i += p;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
p += 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let mut count = 0;
|
|
18
|
+
for p in 2..=n {
|
|
19
|
+
if primes[p] {
|
|
20
|
+
count += 1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
count
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn main() {
|
|
27
|
+
let args: Vec<String> = env::args().collect();
|
|
28
|
+
let n = if args.len() > 1 {
|
|
29
|
+
args[1].parse().unwrap_or(1000000)
|
|
30
|
+
} else {
|
|
31
|
+
1000000
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
println!("{}", sieve(n));
|
|
35
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <vector>
|
|
3
|
+
#include <cstdlib>
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
#include <random>
|
|
6
|
+
|
|
7
|
+
using namespace std;
|
|
8
|
+
|
|
9
|
+
int main(int argc, char* argv[]) {
|
|
10
|
+
int n = 1000000;
|
|
11
|
+
if (argc > 1) n = atoi(argv[1]);
|
|
12
|
+
|
|
13
|
+
vector<int> data(n);
|
|
14
|
+
random_device rd;
|
|
15
|
+
mt19937 gen(rd());
|
|
16
|
+
uniform_int_distribution<> dis(0, 1000000);
|
|
17
|
+
|
|
18
|
+
for(int i=0; i<n; ++i) data[i] = dis(gen);
|
|
19
|
+
|
|
20
|
+
sort(data.begin(), data.end());
|
|
21
|
+
|
|
22
|
+
cout << data[0] << endl;
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"math/rand"
|
|
6
|
+
"os"
|
|
7
|
+
"sort"
|
|
8
|
+
"strconv"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
func main() {
|
|
12
|
+
n := 1000000
|
|
13
|
+
if len(os.Args) > 1 {
|
|
14
|
+
if val, err := strconv.Atoi(os.Args[1]); err == nil {
|
|
15
|
+
n = val
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
data := make([]int, n)
|
|
20
|
+
for i := 0; i < n; i++ {
|
|
21
|
+
data[i] = rand.Intn(1000000)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
sort.Ints(data)
|
|
25
|
+
fmt.Println(data[0])
|
|
26
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const args = process.argv.slice(2);
|
|
2
|
+
const n = args.length > 0 ? parseInt(args[0]) : 1000000;
|
|
3
|
+
|
|
4
|
+
const data = new Int32Array(n);
|
|
5
|
+
for (let i = 0; i < n; i++) {
|
|
6
|
+
data[i] = Math.floor(Math.random() * 1000000);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
data.sort();
|
|
10
|
+
|
|
11
|
+
console.log(data[0]);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import random
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
sys.setrecursionlimit(2000000)
|
|
6
|
+
|
|
7
|
+
def quick_sort(arr):
|
|
8
|
+
if len(arr) <= 1:
|
|
9
|
+
return arr
|
|
10
|
+
pivot = arr[len(arr) // 2]
|
|
11
|
+
left = [x for x in arr if x < pivot]
|
|
12
|
+
middle = [x for x in arr if x == pivot]
|
|
13
|
+
right = [x for x in arr if x > pivot]
|
|
14
|
+
return quick_sort(left) + middle + quick_sort(right)
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
n = 1000000
|
|
18
|
+
if len(sys.argv) > 1:
|
|
19
|
+
n = int(sys.argv[1])
|
|
20
|
+
|
|
21
|
+
# Generate random data
|
|
22
|
+
data = [random.randint(0, 1000000) for _ in range(n)]
|
|
23
|
+
|
|
24
|
+
sorted_data = quick_sort(data)
|
|
25
|
+
# Print first element to prevent optimization
|
|
26
|
+
print(sorted_data[0])
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
use std::env;
|
|
2
|
+
|
|
3
|
+
struct Lcg {
|
|
4
|
+
state: u64,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
impl Lcg {
|
|
8
|
+
fn new(seed: u64) -> Self {
|
|
9
|
+
Lcg { state: seed }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
fn next(&mut self) -> u32 {
|
|
13
|
+
// Linear Congruential Generator config (same as glibc's rand)
|
|
14
|
+
self.state = (self.state.wrapping_mul(1103515245).wrapping_add(12345)) % 2147483648;
|
|
15
|
+
self.state as u32
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fn gen_range(&mut self, range: std::ops::Range<i32>) -> i32 {
|
|
19
|
+
let min = range.start;
|
|
20
|
+
let max = range.end;
|
|
21
|
+
let width = (max - min) as u32;
|
|
22
|
+
(self.next() % width) as i32 + min
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn main() {
|
|
27
|
+
let args: Vec<String> = env::args().collect();
|
|
28
|
+
let n = if args.len() > 1 {
|
|
29
|
+
args[1].parse().unwrap_or(1000000)
|
|
30
|
+
} else {
|
|
31
|
+
1000000
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
let mut rng = Lcg::new(12345);
|
|
35
|
+
let mut data: Vec<i32> = (0..n).map(|_| rng.gen_range(0..1000000)).collect();
|
|
36
|
+
|
|
37
|
+
data.sort();
|
|
38
|
+
|
|
39
|
+
println!("{}", data[0]);
|
|
40
|
+
}
|
velocicode/config.yaml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
languages:
|
|
2
|
+
python:
|
|
3
|
+
run: "python3 {source}"
|
|
4
|
+
cpp:
|
|
5
|
+
compile: "g++ -O3 -std=c++11 {source} -o {out}"
|
|
6
|
+
run: "{out}"
|
|
7
|
+
rust:
|
|
8
|
+
compile: "rustc -O {source} -o {out}"
|
|
9
|
+
run: "{out}"
|
|
10
|
+
javascript:
|
|
11
|
+
run: "node {source}"
|
|
12
|
+
go:
|
|
13
|
+
compile: "go build -o {out} {source}"
|
|
14
|
+
run: "{out}"
|
|
15
|
+
dependencies:
|
|
16
|
+
rust: [rand]
|
velocicode/main.py
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import yaml
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from glob import glob
|
|
6
|
+
import shutil
|
|
7
|
+
from .runner import BenchmarkRunner
|
|
8
|
+
from .reporter import print_table
|
|
9
|
+
from .system_info import get_system_info
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.panel import Panel
|
|
12
|
+
from rich.prompt import Confirm
|
|
13
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
14
|
+
from rich import print as rprint
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
def check_dependencies(config, verbose=True):
|
|
19
|
+
if verbose:
|
|
20
|
+
rprint(Panel("Checking System Dependencies", style="bold blue"))
|
|
21
|
+
|
|
22
|
+
languages = config.get('languages', {})
|
|
23
|
+
valid_langs = set()
|
|
24
|
+
missing_langs = set()
|
|
25
|
+
|
|
26
|
+
for lang, cfg in languages.items():
|
|
27
|
+
# Determine the command to check
|
|
28
|
+
# If 'compile' exists, check the compiler. Else check 'run'.
|
|
29
|
+
cmd_str = cfg.get('compile') or cfg.get('run')
|
|
30
|
+
if not cmd_str:
|
|
31
|
+
if verbose:
|
|
32
|
+
rprint(f"[yellow]WARN[/yellow] {lang}: No command defined")
|
|
33
|
+
continue
|
|
34
|
+
|
|
35
|
+
# simpler parsing: assume command is the first word
|
|
36
|
+
program = cmd_str.split()[0]
|
|
37
|
+
|
|
38
|
+
path = shutil.which(program)
|
|
39
|
+
if path:
|
|
40
|
+
if verbose:
|
|
41
|
+
rprint(f"[green]✔[/green] {lang:<12} (Found: [cyan]{program}[/cyan])")
|
|
42
|
+
valid_langs.add(lang)
|
|
43
|
+
else:
|
|
44
|
+
if verbose:
|
|
45
|
+
rprint(f"[red]✘[/red] {lang:<12} (Missing: [bold]{program}[/bold])")
|
|
46
|
+
missing_langs.add(lang)
|
|
47
|
+
|
|
48
|
+
return valid_langs, missing_langs
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_base_dir():
|
|
52
|
+
return os.path.dirname(os.path.abspath(__file__))
|
|
53
|
+
|
|
54
|
+
def load_config():
|
|
55
|
+
path = os.path.join(get_base_dir(), "config.yaml")
|
|
56
|
+
if not os.path.exists(path):
|
|
57
|
+
print(f"Config file not found: {path}")
|
|
58
|
+
sys.exit(1)
|
|
59
|
+
with open(path, 'r') as f:
|
|
60
|
+
return yaml.safe_load(f)
|
|
61
|
+
|
|
62
|
+
def discover_benchmarks():
|
|
63
|
+
base_dir = os.path.join(get_base_dir(), "benchmarks")
|
|
64
|
+
# Structure: benchmarks/<algo>/<lang>/<file>
|
|
65
|
+
# We want to find all <algo> directories
|
|
66
|
+
if not os.path.exists(base_dir):
|
|
67
|
+
return []
|
|
68
|
+
return [d for d in os.listdir(base_dir) if os.path.isdir(os.path.join(base_dir, d))]
|
|
69
|
+
|
|
70
|
+
def main():
|
|
71
|
+
parser = argparse.ArgumentParser(description="Velocicode - Programming Language Speed Benchmark Tool")
|
|
72
|
+
parser.add_argument("action", choices=["run", "list", "check"], help="Action to perform")
|
|
73
|
+
parser.add_argument("--filter-algo", help="Filter by specific algorithm name")
|
|
74
|
+
parser.add_argument("--filter-lang", help="Filter by specific languages (comma separated)")
|
|
75
|
+
parser.add_argument("--iter", type=int, default=5, help="Number of iterations per benchmark")
|
|
76
|
+
parser.add_argument("--json", help="Export results to a JSON file")
|
|
77
|
+
parser.add_argument("--html", help="Export results to an interactive HTML report")
|
|
78
|
+
|
|
79
|
+
args = parser.parse_args()
|
|
80
|
+
|
|
81
|
+
config = load_config()
|
|
82
|
+
|
|
83
|
+
if args.action == "check":
|
|
84
|
+
check_dependencies(config)
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
runner = BenchmarkRunner(config)
|
|
88
|
+
|
|
89
|
+
algos = discover_benchmarks()
|
|
90
|
+
if args.filter_algo:
|
|
91
|
+
algos = [a for a in algos if a == args.filter_algo]
|
|
92
|
+
|
|
93
|
+
target_langs = None
|
|
94
|
+
if args.filter_lang:
|
|
95
|
+
target_langs = args.filter_lang.split(',')
|
|
96
|
+
|
|
97
|
+
results = []
|
|
98
|
+
|
|
99
|
+
if args.action == "list":
|
|
100
|
+
print("Available benchmarks:")
|
|
101
|
+
for a in algos:
|
|
102
|
+
print(f" - {a}")
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
if args.action == "run":
|
|
106
|
+
# 1. Display System Info
|
|
107
|
+
sys_info = get_system_info()
|
|
108
|
+
info_text = f"""
|
|
109
|
+
[bold]OS:[/bold] {sys_info['os']}
|
|
110
|
+
[bold]CPU:[/bold] {sys_info['cpu']}
|
|
111
|
+
[bold]Arch:[/bold] {sys_info['arch']}
|
|
112
|
+
[bold]RAM:[/bold] {sys_info['ram']}
|
|
113
|
+
"""
|
|
114
|
+
rprint(Panel(info_text.strip(), title="System Information", border_style="green"))
|
|
115
|
+
|
|
116
|
+
# 2. Check Dependencies
|
|
117
|
+
valid_langs, missing_langs = check_dependencies(config, verbose=False)
|
|
118
|
+
|
|
119
|
+
if missing_langs:
|
|
120
|
+
rprint(f"[yellow]Warning: The following languages are missing:[/yellow] [bold]{', '.join(missing_langs)}[/bold]")
|
|
121
|
+
if not Confirm.ask("Do you want to continue running valid languages only?"):
|
|
122
|
+
rprint("[red]Aborted.[/red]")
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
base_dir = os.path.join(get_base_dir(), "benchmarks")
|
|
126
|
+
|
|
127
|
+
# Collect all tasks first
|
|
128
|
+
tasks_to_run = []
|
|
129
|
+
for algo in algos:
|
|
130
|
+
algo_dir = os.path.join(base_dir, algo)
|
|
131
|
+
lang_dirs = [d for d in os.listdir(algo_dir) if os.path.isdir(os.path.join(algo_dir, d)) and d != 'bin']
|
|
132
|
+
|
|
133
|
+
for lang in lang_dirs:
|
|
134
|
+
if target_langs and lang not in target_langs:
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
# SKIP if missing
|
|
138
|
+
if lang in missing_langs:
|
|
139
|
+
continue
|
|
140
|
+
|
|
141
|
+
ext_map = {
|
|
142
|
+
'python': 'main.py',
|
|
143
|
+
'cpp': 'main.cpp',
|
|
144
|
+
'rust': 'main.rs',
|
|
145
|
+
'go': 'main.go',
|
|
146
|
+
'javascript': 'main.js'
|
|
147
|
+
}
|
|
148
|
+
expected_file = ext_map.get(lang)
|
|
149
|
+
if not expected_file:
|
|
150
|
+
continue
|
|
151
|
+
full_path = os.path.join(algo_dir, lang, expected_file)
|
|
152
|
+
if not os.path.exists(full_path):
|
|
153
|
+
continue
|
|
154
|
+
tasks_to_run.append((algo, lang, full_path))
|
|
155
|
+
|
|
156
|
+
if not tasks_to_run:
|
|
157
|
+
rprint("[yellow]No benchmarks found to run.[/yellow]")
|
|
158
|
+
return
|
|
159
|
+
|
|
160
|
+
with Progress(
|
|
161
|
+
SpinnerColumn(),
|
|
162
|
+
TextColumn("[progress.description]{task.description}"),
|
|
163
|
+
transient=True
|
|
164
|
+
) as progress:
|
|
165
|
+
for algo, lang, full_path in tasks_to_run:
|
|
166
|
+
# Initial task description
|
|
167
|
+
desc_tpl = f"[bold cyan]{algo}[/bold cyan] ([magenta]{lang}[/magenta])"
|
|
168
|
+
task_id = progress.add_task(f"{desc_tpl}: Starting...", total=None)
|
|
169
|
+
|
|
170
|
+
def update_status(msg):
|
|
171
|
+
# update progress description
|
|
172
|
+
progress.update(task_id, description=f"{desc_tpl}: {msg}")
|
|
173
|
+
|
|
174
|
+
stats = runner.run_benchmark(lang, full_path, iterations=args.iter, on_status=update_status)
|
|
175
|
+
progress.remove_task(task_id)
|
|
176
|
+
|
|
177
|
+
if stats:
|
|
178
|
+
results.append({
|
|
179
|
+
'benchmark': algo,
|
|
180
|
+
'language': lang,
|
|
181
|
+
**stats
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
print_table(results)
|
|
185
|
+
|
|
186
|
+
if args.json:
|
|
187
|
+
import json
|
|
188
|
+
with open(args.json, 'w') as f:
|
|
189
|
+
json.dump(results, f, indent=2)
|
|
190
|
+
rprint(f"[green]JSON results exported to:[/green] {args.json}")
|
|
191
|
+
|
|
192
|
+
if args.html:
|
|
193
|
+
from .report_generator import generate_html_report
|
|
194
|
+
generate_html_report(results, args.html)
|
|
195
|
+
rprint(f"[green]HTML report generated at:[/green] {args.html}")
|
|
196
|
+
|
|
197
|
+
def interactive_menu():
|
|
198
|
+
rprint(Panel.fit("[bold cyan]Velocicode[/bold cyan]\n[dim]High-Performance Benchmark CLI[/dim]", title="Welcome", border_style="blue"))
|
|
199
|
+
print("1. Run All Benchmarks")
|
|
200
|
+
print("2. Run Specific Algorithm")
|
|
201
|
+
print("3. Run Specific Language")
|
|
202
|
+
print("4. Check Dependencies")
|
|
203
|
+
print("5. Exit")
|
|
204
|
+
|
|
205
|
+
choice = input("Enter choice: ").strip()
|
|
206
|
+
|
|
207
|
+
if choice == '1':
|
|
208
|
+
return ["run"]
|
|
209
|
+
elif choice == '2':
|
|
210
|
+
algos = discover_benchmarks()
|
|
211
|
+
print("\n[bold]Available Algorithms:[/bold]")
|
|
212
|
+
for i, a in enumerate(algos):
|
|
213
|
+
print(f"{i+1}. {a}")
|
|
214
|
+
idx = input("Select algorithm number: ").strip()
|
|
215
|
+
try:
|
|
216
|
+
algo = algos[int(idx)-1]
|
|
217
|
+
return ["run", "--filter-algo", algo]
|
|
218
|
+
except (ValueError, IndexError):
|
|
219
|
+
print("Invalid selection.")
|
|
220
|
+
return interactive_menu()
|
|
221
|
+
elif choice == '3':
|
|
222
|
+
lang = input("Enter language (e.g. python, cpp): ").strip()
|
|
223
|
+
return ["run", "--filter-lang", lang]
|
|
224
|
+
elif choice == '4':
|
|
225
|
+
return ["check"]
|
|
226
|
+
elif choice == '5':
|
|
227
|
+
sys.exit(0)
|
|
228
|
+
else:
|
|
229
|
+
print("Invalid choice.")
|
|
230
|
+
return interactive_menu()
|
|
231
|
+
|
|
232
|
+
if __name__ == "__main__":
|
|
233
|
+
if len(sys.argv) == 1:
|
|
234
|
+
args = interactive_menu()
|
|
235
|
+
# Hack: modify sys.argv so argparse parses our generated args
|
|
236
|
+
sys.argv = [sys.argv[0]] + args
|
|
237
|
+
main()
|
|
238
|
+
else:
|
|
239
|
+
main()
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import datetime
|
|
3
|
+
|
|
4
|
+
HTML_TEMPLATE = """
|
|
5
|
+
<!DOCTYPE html>
|
|
6
|
+
<html lang="en">
|
|
7
|
+
<head>
|
|
8
|
+
<meta charset="UTF-8">
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10
|
+
<title>Velocicode Benchmark Report</title>
|
|
11
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
12
|
+
<style>
|
|
13
|
+
body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f4f6f8; }}
|
|
14
|
+
.container {{ max-width: 1000px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }}
|
|
15
|
+
h1 {{ color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }}
|
|
16
|
+
.meta {{ color: #7f8c8d; font-size: 0.9em; margin-bottom: 30px; }}
|
|
17
|
+
.benchmark-section {{ margin-bottom: 50px; }}
|
|
18
|
+
.chart-container {{ position: relative; height: 300px; width: 100%; }}
|
|
19
|
+
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
|
|
20
|
+
th, td {{ padding: 10px; text-align: left; border-bottom: 1px solid #eee; }}
|
|
21
|
+
th {{ background-color: #f8f9fa; }}
|
|
22
|
+
.rank-1 {{ color: #f1c40f; font-weight: bold; }} /* Gold */
|
|
23
|
+
.rank-2 {{ color: #95a5a6; font-weight: bold; }} /* Silver */
|
|
24
|
+
.rank-3 {{ color: #cd7f32; font-weight: bold; }} /* Bronze */
|
|
25
|
+
</style>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<div class="container">
|
|
29
|
+
<h1>Velocicode Report</h1>
|
|
30
|
+
<div class="meta">Generated on: {date}</div>
|
|
31
|
+
|
|
32
|
+
<div id="charts"></div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<script>
|
|
36
|
+
const results = {results_json};
|
|
37
|
+
|
|
38
|
+
// Group results by benchmark
|
|
39
|
+
const grouped = {{}};
|
|
40
|
+
results.forEach(r => {{
|
|
41
|
+
if (!grouped[r.benchmark]) grouped[r.benchmark] = [];
|
|
42
|
+
grouped[r.benchmark].push(r);
|
|
43
|
+
}});
|
|
44
|
+
|
|
45
|
+
const container = document.getElementById('charts');
|
|
46
|
+
|
|
47
|
+
// Color palette for languages
|
|
48
|
+
const colors = {{
|
|
49
|
+
'python': '#3572A5',
|
|
50
|
+
'cpp': '#f34b7d',
|
|
51
|
+
'rust': '#dea584',
|
|
52
|
+
'go': '#00ADD8',
|
|
53
|
+
'javascript': '#f1e05a'
|
|
54
|
+
}};
|
|
55
|
+
|
|
56
|
+
for (const [benchName, items] of Object.entries(grouped)) {{
|
|
57
|
+
// Sort by mean time
|
|
58
|
+
items.sort((a, b) => a.mean - b.mean);
|
|
59
|
+
|
|
60
|
+
// Create Section
|
|
61
|
+
const section = document.createElement('div');
|
|
62
|
+
section.className = 'benchmark-section';
|
|
63
|
+
|
|
64
|
+
const title = document.createElement('h2');
|
|
65
|
+
title.textContent = `Benchmark: ${{benchName}}`;
|
|
66
|
+
section.appendChild(title);
|
|
67
|
+
|
|
68
|
+
// Canvas for Chart
|
|
69
|
+
const chartDiv = document.createElement('div');
|
|
70
|
+
chartDiv.className = 'chart-container';
|
|
71
|
+
const canvas = document.createElement('canvas');
|
|
72
|
+
chartDiv.appendChild(canvas);
|
|
73
|
+
section.appendChild(chartDiv);
|
|
74
|
+
|
|
75
|
+
// Table
|
|
76
|
+
const table = document.createElement('table');
|
|
77
|
+
table.innerHTML = `
|
|
78
|
+
<thead>
|
|
79
|
+
<tr>
|
|
80
|
+
<th>Rank</th>
|
|
81
|
+
<th>Language</th>
|
|
82
|
+
<th>Time (s)</th>
|
|
83
|
+
<th>Relative Speed</th>
|
|
84
|
+
</tr>
|
|
85
|
+
</thead>
|
|
86
|
+
<tbody>
|
|
87
|
+
${{items.map((item, index) => {{
|
|
88
|
+
const relative = (item.mean / items[0].mean).toFixed(2) + 'x';
|
|
89
|
+
let rankClass = '';
|
|
90
|
+
let rankIcon = index + 1;
|
|
91
|
+
if (index === 0) {{ rankIcon = '🥇'; rankClass='rank-1'; }}
|
|
92
|
+
if (index === 1) {{ rankIcon = '🥈'; rankClass='rank-2'; }}
|
|
93
|
+
if (index === 2) {{ rankIcon = '🥉'; rankClass='rank-3'; }}
|
|
94
|
+
|
|
95
|
+
return `<tr>
|
|
96
|
+
<td class="${{rankClass}}">${{rankIcon}}</td>
|
|
97
|
+
<td>${{item.language}}</td>
|
|
98
|
+
<td>${{item.mean.toFixed(4)}}</td>
|
|
99
|
+
<td>${{relative}}</td>
|
|
100
|
+
</tr>`;
|
|
101
|
+
}}).join('')}}
|
|
102
|
+
</tbody>
|
|
103
|
+
`;
|
|
104
|
+
section.appendChild(table);
|
|
105
|
+
|
|
106
|
+
container.appendChild(section);
|
|
107
|
+
|
|
108
|
+
// Render Chart
|
|
109
|
+
new Chart(canvas, {{
|
|
110
|
+
type: 'bar',
|
|
111
|
+
data: {{
|
|
112
|
+
labels: items.map(i => i.language),
|
|
113
|
+
datasets: [{{
|
|
114
|
+
label: 'Execution Time (seconds) - Lower is Better',
|
|
115
|
+
data: items.map(i => i.mean),
|
|
116
|
+
backgroundColor: items.map(i => colors[i.language] || '#cccccc'),
|
|
117
|
+
borderColor: '#222',
|
|
118
|
+
borderWidth: 1
|
|
119
|
+
}}]
|
|
120
|
+
}},
|
|
121
|
+
options: {{
|
|
122
|
+
responsive: true,
|
|
123
|
+
maintainAspectRatio: false,
|
|
124
|
+
indexAxis: 'y',
|
|
125
|
+
scales: {{
|
|
126
|
+
x: {{ beginAtZero: true, title: {{ display: true, text: 'Seconds' }} }}
|
|
127
|
+
}}
|
|
128
|
+
}}
|
|
129
|
+
}});
|
|
130
|
+
}}
|
|
131
|
+
</script>
|
|
132
|
+
</body>
|
|
133
|
+
</html>
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
def generate_html_report(results, output_path):
|
|
137
|
+
report_html = HTML_TEMPLATE.format(
|
|
138
|
+
date=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
139
|
+
results_json=json.dumps(results)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
with open(output_path, 'w') as f:
|
|
143
|
+
f.write(report_html)
|
velocicode/reporter.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from rich import print
|
|
2
|
+
from rich.table import Table
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
|
|
5
|
+
def print_table(results):
|
|
6
|
+
if not results:
|
|
7
|
+
print("[yellow]No results to display[/yellow]")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
# 1. Group by Benchmark
|
|
13
|
+
grouped = {}
|
|
14
|
+
for r in results:
|
|
15
|
+
bench_name = r['benchmark']
|
|
16
|
+
if bench_name not in grouped:
|
|
17
|
+
grouped[bench_name] = []
|
|
18
|
+
grouped[bench_name].append(r)
|
|
19
|
+
|
|
20
|
+
# 2. Process each group
|
|
21
|
+
for bench_name, group_results in grouped.items():
|
|
22
|
+
# Sort by mean time (fastest first)
|
|
23
|
+
group_results.sort(key=lambda x: x['mean'])
|
|
24
|
+
|
|
25
|
+
# Determine baseline (fastest)
|
|
26
|
+
if not group_results:
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
fastest_time = group_results[0]['mean']
|
|
30
|
+
|
|
31
|
+
# Create Table
|
|
32
|
+
table = Table(
|
|
33
|
+
title=f"Benchmark: [bold cyan]{bench_name}[/bold cyan]",
|
|
34
|
+
show_header=True,
|
|
35
|
+
header_style="bold white",
|
|
36
|
+
border_style="blue",
|
|
37
|
+
expand=True
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
table.add_column("Rank", style="bold yellow", justify="center", width=4)
|
|
41
|
+
table.add_column("Language", style="magenta", width=12)
|
|
42
|
+
table.add_column("Time (s)", justify="right")
|
|
43
|
+
table.add_column("Relative", justify="right")
|
|
44
|
+
table.add_column("Min (s)", style="dim", justify="right")
|
|
45
|
+
table.add_column("Max (s)", style="dim", justify="right")
|
|
46
|
+
|
|
47
|
+
for i, r in enumerate(group_results):
|
|
48
|
+
# Rank
|
|
49
|
+
rank_display = str(i + 1)
|
|
50
|
+
if i == 0:
|
|
51
|
+
rank_display = "🥇"
|
|
52
|
+
elif i == 1:
|
|
53
|
+
rank_display = "🥈"
|
|
54
|
+
elif i == 2:
|
|
55
|
+
rank_display = "🥉"
|
|
56
|
+
|
|
57
|
+
# Relative Speed
|
|
58
|
+
rel_speed = r['mean'] / fastest_time
|
|
59
|
+
rel_str = f"{rel_speed:.2f}x"
|
|
60
|
+
|
|
61
|
+
# Colorize Relative Speed
|
|
62
|
+
if rel_speed < 1.05:
|
|
63
|
+
rel_style = "[green]"
|
|
64
|
+
elif rel_speed < 5.0:
|
|
65
|
+
rel_style = "[yellow]"
|
|
66
|
+
else:
|
|
67
|
+
rel_style = "[red]"
|
|
68
|
+
|
|
69
|
+
table.add_row(
|
|
70
|
+
rank_display,
|
|
71
|
+
r['language'],
|
|
72
|
+
f"{r['mean']:.4f}",
|
|
73
|
+
f"{rel_style}{rel_str}[/]",
|
|
74
|
+
f"{r['min']:.4f}",
|
|
75
|
+
f"{r['max']:.4f}"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
console.print(table)
|
|
79
|
+
console.print("") # Newline between tables
|
velocicode/runner.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import time
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
|
|
6
|
+
class BenchmarkRunner:
|
|
7
|
+
def __init__(self, config):
|
|
8
|
+
self.config = config
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def run_benchmark(self, language, source_path, iterations=5, on_status=None):
|
|
13
|
+
def log(msg):
|
|
14
|
+
if on_status:
|
|
15
|
+
on_status(msg)
|
|
16
|
+
else:
|
|
17
|
+
print(msg)
|
|
18
|
+
|
|
19
|
+
lang_config = self.config.get('languages', {}).get(language)
|
|
20
|
+
if not lang_config:
|
|
21
|
+
raise ValueError(f"Unknown language: {language}")
|
|
22
|
+
|
|
23
|
+
# Prepare output binary path if needed
|
|
24
|
+
bin_dir = os.path.join(os.path.dirname(source_path), 'bin')
|
|
25
|
+
os.makedirs(bin_dir, exist_ok=True)
|
|
26
|
+
bin_name = f"runner_{language}"
|
|
27
|
+
bin_path = os.path.join(bin_dir, bin_name)
|
|
28
|
+
|
|
29
|
+
# Compile if necessary
|
|
30
|
+
try:
|
|
31
|
+
compile_cmd_tpl = lang_config.get('compile')
|
|
32
|
+
if compile_cmd_tpl:
|
|
33
|
+
cmd = compile_cmd_tpl.format(source=source_path, out=bin_path)
|
|
34
|
+
log(f"Compiling...")
|
|
35
|
+
subprocess.check_call(cmd, shell=True)
|
|
36
|
+
else:
|
|
37
|
+
# No compilation needed
|
|
38
|
+
pass
|
|
39
|
+
except subprocess.CalledProcessError as e:
|
|
40
|
+
log(f"[red]Compilation failed[/red]: {e}")
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
run_cmd_tpl = lang_config.get('run')
|
|
44
|
+
# If compiled, use bin_path, else use source_path
|
|
45
|
+
cmd = run_cmd_tpl.format(source=source_path, out=bin_path)
|
|
46
|
+
|
|
47
|
+
times = []
|
|
48
|
+
for i in range(iterations):
|
|
49
|
+
log(f"Running iteration {i+1}/{iterations}...")
|
|
50
|
+
start = time.time()
|
|
51
|
+
try:
|
|
52
|
+
subprocess.check_call(cmd, shell=True, stdout=subprocess.DEVNULL)
|
|
53
|
+
duration = time.time() - start
|
|
54
|
+
times.append(duration)
|
|
55
|
+
except subprocess.CalledProcessError as e:
|
|
56
|
+
log(f"[red]Runtime error[/red]: {e}")
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
# simple stats
|
|
60
|
+
return {
|
|
61
|
+
'mean': sum(times) / len(times),
|
|
62
|
+
'min': min(times),
|
|
63
|
+
'max': max(times),
|
|
64
|
+
'count': len(times)
|
|
65
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import platform
|
|
2
|
+
import psutil
|
|
3
|
+
import cpuinfo
|
|
4
|
+
|
|
5
|
+
def get_system_info():
|
|
6
|
+
"""
|
|
7
|
+
Returns a dictionary containing system information.
|
|
8
|
+
"""
|
|
9
|
+
cpu_info = cpuinfo.get_cpu_info()
|
|
10
|
+
cpu_model = cpu_info.get('brand_raw', 'Unknown CPU')
|
|
11
|
+
arch = platform.machine()
|
|
12
|
+
|
|
13
|
+
ram_bytes = psutil.virtual_memory().total
|
|
14
|
+
ram_gb = ram_bytes / (1024**3)
|
|
15
|
+
|
|
16
|
+
os_info = f"{platform.system()} {platform.release()}"
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
"os": os_info,
|
|
20
|
+
"cpu": cpu_model,
|
|
21
|
+
"arch": arch,
|
|
22
|
+
"ram": f"{ram_gb:.1f} GB"
|
|
23
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Velocicode
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: A CLI tool for programming language speed benchmarks
|
|
5
|
+
Author-email: Code Agent <agent@example.com>
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.7
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: pyyaml
|
|
13
|
+
Requires-Dist: rich>=13.0.0
|
|
14
|
+
Requires-Dist: psutil
|
|
15
|
+
Requires-Dist: py-cpuinfo
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# Velocicode 🚀
|
|
19
|
+
|
|
20
|
+
**Velocicode** is a high-performance command-line tool for benchmarking programming language speeds. It allows you to run standard algorithms across multiple languages and compare their execution time with professional, interactive reports.
|
|
21
|
+
|
|
22
|
+
## Features ✨
|
|
23
|
+
|
|
24
|
+
- **Multi-Language Support**: Benchmarks **Python**, **C++**, **Rust**, **Go**, and **JavaScript** (Node.js).
|
|
25
|
+
- **Smart Execution**:
|
|
26
|
+
- **System Info**: Auto-detects your CPU, RAM, and OS.
|
|
27
|
+
- **Dependency Check**: Automatically checks for compilers and skips missing languages.
|
|
28
|
+
- **Premium UI**:
|
|
29
|
+
- Beautiful terminal output using the **Rich** library.
|
|
30
|
+
- Rankings with Medals (🥇 🥈 🥉).
|
|
31
|
+
- Relative Speed comparisons (e.g., `1.00x` vs `45.9x`).
|
|
32
|
+
- **Data Export**:
|
|
33
|
+
- **JSON**: Raw data export for analysis.
|
|
34
|
+
- **HTML**: Interactive reports with **Charts** for presentations.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install velocicode
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
### 1. Run Benchmarks
|
|
45
|
+
|
|
46
|
+
Run all benchmarks with default settings:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
velocicode run
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The tool will display your system information and check if you have the necessary compilers. If some are missing, it will ask if you want to proceed with the available ones.
|
|
53
|
+
|
|
54
|
+
Filter by specific algorithm or language:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Run only Matrix Multiplication in Rust and Go
|
|
58
|
+
velocicode run --filter-algo matrix_mul --filter-lang rust,go
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Generate Reports 📊
|
|
62
|
+
|
|
63
|
+
Export results to JSON or generate a visual HTML report:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
velocicode run --html report.html --json results.json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Open `report.html` in your browser to see interactive bar charts!
|
|
70
|
+
|
|
71
|
+
### 3. Check Compilers
|
|
72
|
+
|
|
73
|
+
Velocicode relies on system compilers. Check what you have installed:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
velocicode check
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Requirements
|
|
80
|
+
|
|
81
|
+
> [!IMPORTANT]
|
|
82
|
+
> This tool requires external compilers. `pip` installs the runner, but you need the languages installed:
|
|
83
|
+
|
|
84
|
+
- **Python 3.7+**
|
|
85
|
+
- `g++` (for C++)
|
|
86
|
+
- `rustc` (for Rust)
|
|
87
|
+
- `go` (for Go)
|
|
88
|
+
- `node` (for JavaScript)
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
velocicode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
velocicode/config.yaml,sha256=-9AMoCq1SsHgbBzDk0DZhnwxGev_hFM1mq_az-teJnw,325
|
|
3
|
+
velocicode/main.py,sha256=YSTF4zhguej2QZg8a-miK0UgLV9Sik2VUCnC57WycCE,8437
|
|
4
|
+
velocicode/report_generator.py,sha256=hXaO6Vf6AxVep4SYlJifeoAYRnWwCjfjSluOb1NxOQQ,5507
|
|
5
|
+
velocicode/reporter.py,sha256=o7byb2SpSF1o6kbr9yhWdLPV3-wem8L6_gY-0DoTz8o,2484
|
|
6
|
+
velocicode/runner.py,sha256=8sUhLJhTCL5wWGZ6IJcaDn4MHdUugxUTINds2LKdFXM,2104
|
|
7
|
+
velocicode/system_info.py,sha256=pUHUr6aRnGeXAprcYgCpLntzhpbLRpU50DXvfWz5Fu4,544
|
|
8
|
+
velocicode/benchmarks/fibonacci/cpp/main.cpp,sha256=fU0cJUofLBHXM6i_d4LA-f8xZoGyLBQvCTFS2mqHrXA,285
|
|
9
|
+
velocicode/benchmarks/fibonacci/go/main.go,sha256=a94v7GVuqpVkGrjFFU6xRXZ4B4zJ-IAbYIG0CRM2pvI,274
|
|
10
|
+
velocicode/benchmarks/fibonacci/javascript/main.js,sha256=A-rTit4G6USJ2FWaxTBC18O41AdCn84kWv9S0R5JIVE,193
|
|
11
|
+
velocicode/benchmarks/fibonacci/python/main.py,sha256=gYD1pC5jKckc1GvqoDpppToPssKn0w7v73LsLo5okF8,203
|
|
12
|
+
velocicode/benchmarks/fibonacci/rust/main.rs,sha256=tXIltVAP4M6mEVGTe5IkFTmWHwZiGReTGpnwwf3PiUY,304
|
|
13
|
+
velocicode/benchmarks/matrix_mul/cpp/main.cpp,sha256=H1wLUuMfsLP1l9qH4igXWFiRnDTfBMck8WHv5TcfTIM,1004
|
|
14
|
+
velocicode/benchmarks/matrix_mul/go/main.go,sha256=_dN1D650fZp7dp0utdpqbwO8UXebmwNnTmDIN76wKR0,737
|
|
15
|
+
velocicode/benchmarks/matrix_mul/javascript/main.js,sha256=_trWvLtlwzme6bLudDkWljPb9teo8GRikv1m7OqWh6k,693
|
|
16
|
+
velocicode/benchmarks/matrix_mul/python/main.py,sha256=j2c9tJaOA5Zn4aB9cPAQvtlOuQOfgHcPyGWAXK9fpPg,590
|
|
17
|
+
velocicode/benchmarks/matrix_mul/rust/main.rs,sha256=IT15ptLggEP_3q_iZ1RBIAs3pPPteZ6ZAvnkogELPOw,827
|
|
18
|
+
velocicode/benchmarks/primes/cpp/main.cpp,sha256=dtBbXZ_Z_grhVV3rW0TX_gYreWW5kaeMB1AFZt2gm-U,558
|
|
19
|
+
velocicode/benchmarks/primes/go/main.go,sha256=PxZFltOWXxqK7XpBPC7tRfLsr502j0-ORlYvj8ZZhNI,519
|
|
20
|
+
velocicode/benchmarks/primes/javascript/main.js,sha256=6ok5TFHOX-P_yemnBTjTDMeHr7BqqsTB9uh92-kNfaA,465
|
|
21
|
+
velocicode/benchmarks/primes/python/main.py,sha256=jhlKq2KDMYnjmVt1eFzgodFFF3EPv1hlGjmHOqHt1x4,470
|
|
22
|
+
velocicode/benchmarks/primes/rust/main.rs,sha256=-fuEJFULB9MHpxGmdc1HlD7lTL9ZOpbEj0HWiRrjWDA,643
|
|
23
|
+
velocicode/benchmarks/quicksort/cpp/main.cpp,sha256=2s1l6zrBJuUjiY_BZnFcN01ow9l4GcyGZzmRwJcSOhE,462
|
|
24
|
+
velocicode/benchmarks/quicksort/go/main.go,sha256=9I8Onqf_tzqoRqDeP-RTp2t47ofYkYbR277-ABF_ias,323
|
|
25
|
+
velocicode/benchmarks/quicksort/javascript/main.js,sha256=wUSfEIb4QIk-r1u5P1aaoKu9n7Rd8FpI1mDpgE1N3WE,246
|
|
26
|
+
velocicode/benchmarks/quicksort/python/main.py,sha256=UBpRHGJ3r32UAYmpwa_8cN8urI1O-VH1Xza-OduP-y0,652
|
|
27
|
+
velocicode/benchmarks/quicksort/rust/main.rs,sha256=30uWtnz8ZkHcfiqMKln_nTHmQcytJ-XtY-TOk0kzZKo,918
|
|
28
|
+
velocicode-0.5.0.dist-info/licenses/LICENSE,sha256=ESYyLizI0WWtxMeS7rGVcX3ivMezm-HOd5WdeOh-9oU,1056
|
|
29
|
+
velocicode-0.5.0.dist-info/METADATA,sha256=Ug1b2roBf3KSWpMN8j-7UDWCvHZ_M3KBAG1vwbeDdnE,2482
|
|
30
|
+
velocicode-0.5.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
31
|
+
velocicode-0.5.0.dist-info/entry_points.txt,sha256=OhCJJRwEh3bhmwUpd1oML4Ta-KLX3a9dq7Mu7mNi-pc,52
|
|
32
|
+
velocicode-0.5.0.dist-info/top_level.txt,sha256=zphesZGvGtNa8jw8Bpmx9byQPHk-YnNEWuK7s_hdX0E,11
|
|
33
|
+
velocicode-0.5.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
velocicode
|