@razinshafayet/typedjs 0.2.0 → 0.2.2
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.
- package/benchmarks/README.md +22 -0
- package/benchmarks/benchmark_report.html +46 -0
- package/benchmarks/complex.tjs +107 -0
- package/benchmarks/complex.ts +109 -0
- package/benchmarks/loop.tjs +13 -0
- package/benchmarks/loop.ts +13 -0
- package/benchmarks/make-chart.js +72 -0
- package/benchmarks/results.json +77 -0
- package/benchmarks/run.js +159 -0
- package/benchmarks/simple.tjs +31 -0
- package/benchmarks/simple.ts +33 -0
- package/jest.config.cjs +14 -0
- package/package.json +13 -2
- package/src/cli.js +15 -3
- package/src/generator/generator.js +51 -32
- package/tests/analyzer.test.js +113 -0
- package/tests/fix-tests.sh +13 -0
- package/tests/fixtures/invalid/interface-errors.tjs +12 -0
- package/tests/fixtures/invalid/type-mismatches.tjs +5 -0
- package/tests/fixtures/valid/functions.tjs +13 -0
- package/tests/fixtures/valid/interfaces.tjs +13 -0
- package/tests/fixtures/valid/simple-types.tjs +6 -0
- package/tests/generator.test.js +91 -0
- package/tests/integration.test.js +90 -0
- package/tests/parser.test.js +108 -0
- package/tests/setup.js +16 -0
- package/tsconfig.json +7 -0
- package/example.tjs +0 -14
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# TypedJS Benchmarks
|
|
2
|
+
|
|
3
|
+
## Running Benchmarks
|
|
4
|
+
```bash
|
|
5
|
+
cd benchmarks
|
|
6
|
+
node run.js
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Benchmark Files
|
|
10
|
+
|
|
11
|
+
- `simple.tjs` / `simple.ts` - Basic types and functions
|
|
12
|
+
- `complex.tjs` / `complex.ts` - Nested types, interfaces, complex logic
|
|
13
|
+
|
|
14
|
+
## What Gets Measured
|
|
15
|
+
|
|
16
|
+
1. **TypedJS Dev Mode** - Runtime type checking enabled
|
|
17
|
+
2. **TypedJS Prod Mode** - Types stripped, no runtime overhead
|
|
18
|
+
3. **TypeScript** - Compile + execution time
|
|
19
|
+
|
|
20
|
+
## Results
|
|
21
|
+
|
|
22
|
+
Results are saved to `results.json` after each run.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<title>TypedJS Benchmark Report</title>
|
|
6
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
7
|
+
<style>
|
|
8
|
+
body { font-family: -apple-system, sans-serif; padding: 40px; background: #f9f9f9; }
|
|
9
|
+
.container { max-width: 900px; margin: auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
|
10
|
+
h1 { text-align: center; color: #333; }
|
|
11
|
+
.summary { margin-bottom: 30px; border-left: 5px solid #4bc0c0; padding-left: 15px; }
|
|
12
|
+
</style>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<div class="container">
|
|
16
|
+
<h1>🚀 TypedJS vs TypeScript</h1>
|
|
17
|
+
<div class="summary">
|
|
18
|
+
<p><strong>Metric:</strong> Total turnaround time (Compilation + Execution) in <strong>milliseconds</strong>.</p>
|
|
19
|
+
<p>Lower is better. Results based on your local system benchmark.</p>
|
|
20
|
+
</div>
|
|
21
|
+
<canvas id="benchmarkChart"></canvas>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<script>
|
|
25
|
+
const ctx = document.getElementById('benchmarkChart').getContext('2d');
|
|
26
|
+
new Chart(ctx, {
|
|
27
|
+
type: 'bar',
|
|
28
|
+
data: {
|
|
29
|
+
labels: ["Simple Benchmark","Complex Benchmark","Loop Benchmark (Torture Test)"],
|
|
30
|
+
datasets: [
|
|
31
|
+
{ label: 'TypedJS (Dev)', data: [null,null,null], backgroundColor: '#ffce56' },
|
|
32
|
+
{ label: 'TypedJS (Prod)', data: [null,null,null], backgroundColor: '#4bc0c0' },
|
|
33
|
+
{ label: 'TypeScript (Total)', data: [7514,7707,7669], backgroundColor: '#36a2eb' }
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
options: {
|
|
37
|
+
responsive: true,
|
|
38
|
+
scales: { y: { beginAtZero: true, title: { display: true, text: 'Time (ms)' } } },
|
|
39
|
+
plugins: {
|
|
40
|
+
title: { display: true, text: 'Developer Velocity: Save to Run Time' }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
</script>
|
|
45
|
+
</body>
|
|
46
|
+
</html>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Complex benchmark - nested types, generics, unions
|
|
2
|
+
type Status = "active" | "inactive" | "pending";
|
|
3
|
+
type ID = string | number;
|
|
4
|
+
|
|
5
|
+
interface Address {
|
|
6
|
+
street: string;
|
|
7
|
+
city: string;
|
|
8
|
+
zipCode: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface Customer {
|
|
12
|
+
id: ID;
|
|
13
|
+
name: string;
|
|
14
|
+
email: string;
|
|
15
|
+
status: Status;
|
|
16
|
+
address: Address;
|
|
17
|
+
orders: Array<Order>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface Order {
|
|
21
|
+
orderId: ID;
|
|
22
|
+
amount: number;
|
|
23
|
+
date: string;
|
|
24
|
+
items: Array<OrderItem>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface OrderItem {
|
|
28
|
+
productId: ID;
|
|
29
|
+
name: string;
|
|
30
|
+
quantity: number;
|
|
31
|
+
price: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function createCustomer(id: ID, name: string, email: string): Customer {
|
|
35
|
+
return {
|
|
36
|
+
id: id,
|
|
37
|
+
name: name,
|
|
38
|
+
email: email,
|
|
39
|
+
status: "active",
|
|
40
|
+
address: {
|
|
41
|
+
street: "123 Main St",
|
|
42
|
+
city: "Springfield",
|
|
43
|
+
zipCode: "12345"
|
|
44
|
+
},
|
|
45
|
+
orders: []
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function createOrder(orderId: ID, customerId: ID): Order {
|
|
50
|
+
return {
|
|
51
|
+
orderId: orderId,
|
|
52
|
+
amount: 0,
|
|
53
|
+
date: "2024-01-01",
|
|
54
|
+
items: []
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function addOrderItem(order: Order, item: OrderItem): Order {
|
|
59
|
+
order.items.push(item);
|
|
60
|
+
order.amount = order.amount + (item.price * item.quantity);
|
|
61
|
+
return order;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function calculateCustomerTotal(customer: Customer): number {
|
|
65
|
+
let total: number = 0;
|
|
66
|
+
for (let i: number = 0; i < customer.orders.length; i++) {
|
|
67
|
+
total = total + customer.orders[i].amount;
|
|
68
|
+
}
|
|
69
|
+
return total;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Run complex benchmark
|
|
73
|
+
let customers: Array<Customer> = [];
|
|
74
|
+
|
|
75
|
+
for (let i: number = 0; i < 500; i++) {
|
|
76
|
+
let customer: Customer = createCustomer(
|
|
77
|
+
i,
|
|
78
|
+
"Customer " + i,
|
|
79
|
+
"customer" + i + "@example.com"
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
for (let j: number = 0; j < 3; j++) {
|
|
83
|
+
let order: Order = createOrder(i * 100 + j, i);
|
|
84
|
+
|
|
85
|
+
for (let k: number = 0; k < 5; k++) {
|
|
86
|
+
let item: OrderItem = {
|
|
87
|
+
productId: k,
|
|
88
|
+
name: "Product " + k,
|
|
89
|
+
quantity: k + 1,
|
|
90
|
+
price: 10 + k
|
|
91
|
+
};
|
|
92
|
+
order = addOrderItem(order, item);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
customer.orders.push(order);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
customers.push(customer);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let grandTotal: number = 0;
|
|
102
|
+
for (let i: number = 0; i < customers.length; i++) {
|
|
103
|
+
grandTotal = grandTotal + calculateCustomerTotal(customers[i]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log("Processed", customers.length, "customers");
|
|
107
|
+
console.log("Grand total:", grandTotal);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Complex benchmark - nested types, generics, unions
|
|
2
|
+
type Status = "active" | "inactive" | "pending";
|
|
3
|
+
type ID = string | number;
|
|
4
|
+
|
|
5
|
+
interface Address {
|
|
6
|
+
street: string;
|
|
7
|
+
city: string;
|
|
8
|
+
zipCode: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface Customer {
|
|
12
|
+
id: ID;
|
|
13
|
+
name: string;
|
|
14
|
+
email: string;
|
|
15
|
+
status: Status;
|
|
16
|
+
address: Address;
|
|
17
|
+
orders: Array<Order>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface Order {
|
|
21
|
+
orderId: ID;
|
|
22
|
+
amount: number;
|
|
23
|
+
date: string;
|
|
24
|
+
items: Array<OrderItem>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface OrderItem {
|
|
28
|
+
productId: ID;
|
|
29
|
+
name: string;
|
|
30
|
+
quantity: number;
|
|
31
|
+
price: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function createCustomer(id: ID, name: string, email: string): Customer {
|
|
35
|
+
return {
|
|
36
|
+
id: id,
|
|
37
|
+
name: name,
|
|
38
|
+
email: email,
|
|
39
|
+
status: "active",
|
|
40
|
+
address: {
|
|
41
|
+
street: "123 Main St",
|
|
42
|
+
city: "Springfield",
|
|
43
|
+
zipCode: "12345"
|
|
44
|
+
},
|
|
45
|
+
orders: []
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function createOrder(orderId: ID, customerId: ID): Order {
|
|
50
|
+
return {
|
|
51
|
+
orderId: orderId,
|
|
52
|
+
amount: 0,
|
|
53
|
+
date: "2024-01-01",
|
|
54
|
+
items: []
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function addOrderItem(order: Order, item: OrderItem): Order {
|
|
59
|
+
order.items.push(item);
|
|
60
|
+
order.amount = order.amount + (item.price * item.quantity);
|
|
61
|
+
return order;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function calculateCustomerTotal(customer: Customer): number {
|
|
65
|
+
let total: number = 0;
|
|
66
|
+
for (let i: number = 0; i < customer.orders.length; i++) {
|
|
67
|
+
total = total + customer.orders[i].amount;
|
|
68
|
+
}
|
|
69
|
+
return total;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Run complex benchmark
|
|
73
|
+
let customers: Array<Customer> = [];
|
|
74
|
+
|
|
75
|
+
for (let i: number = 0; i < 500; i++) {
|
|
76
|
+
let customer: Customer = createCustomer(
|
|
77
|
+
i,
|
|
78
|
+
"Customer " + i,
|
|
79
|
+
"customer" + i + "@example.com"
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
for (let j: number = 0; j < 3; j++) {
|
|
83
|
+
let order: Order = createOrder(i * 100 + j, i);
|
|
84
|
+
|
|
85
|
+
for (let k: number = 0; k < 5; k++) {
|
|
86
|
+
let item: OrderItem = {
|
|
87
|
+
productId: k,
|
|
88
|
+
name: "Product " + k,
|
|
89
|
+
quantity: k + 1,
|
|
90
|
+
price: 10 + k
|
|
91
|
+
};
|
|
92
|
+
order = addOrderItem(order, item);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
customer.orders.push(order);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
customers.push(customer);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let grandTotal: number = 0;
|
|
102
|
+
for (let i: number = 0; i < customers.length; i++) {
|
|
103
|
+
grandTotal = grandTotal + calculateCustomerTotal(customers[i]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log("Processed", customers.length, "customers");
|
|
107
|
+
console.log("Grand total:", grandTotal);
|
|
108
|
+
|
|
109
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// benchmarks/loop.tjs
|
|
2
|
+
function add(a: number, b: number): number {
|
|
3
|
+
return a + b;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
let sum: number = 0;
|
|
7
|
+
|
|
8
|
+
// 1,000,000 iterations to stress-test the runtime validator
|
|
9
|
+
for (let i: number = 0; i < 1000000; i++) {
|
|
10
|
+
sum = add(sum, 1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
console.log("Computed sum:", sum);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
// Read the results generated by run.js
|
|
9
|
+
const resultsPath = path.join(__dirname, 'results.json');
|
|
10
|
+
if (!fs.existsSync(resultsPath)) {
|
|
11
|
+
console.error("❌ results.json not found! Run 'node run.js' first.");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const data = JSON.parse(fs.readFileSync(resultsPath, 'utf8'));
|
|
16
|
+
|
|
17
|
+
// Process data for Chart.js
|
|
18
|
+
const labels = data.map(r => r.name);
|
|
19
|
+
const tjsDev = data.map(r => parseInt(r.typedjs.dev.time));
|
|
20
|
+
const tjsProd = data.map(r => parseInt(r.typedjs.prod.time));
|
|
21
|
+
const tsTotal = data.map(r => parseInt(r.typescript.totalTime));
|
|
22
|
+
|
|
23
|
+
const htmlTemplate = `
|
|
24
|
+
<!DOCTYPE html>
|
|
25
|
+
<html>
|
|
26
|
+
<head>
|
|
27
|
+
<title>TypedJS Benchmark Report</title>
|
|
28
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
29
|
+
<style>
|
|
30
|
+
body { font-family: -apple-system, sans-serif; padding: 40px; background: #f9f9f9; }
|
|
31
|
+
.container { max-width: 900px; margin: auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
|
32
|
+
h1 { text-align: center; color: #333; }
|
|
33
|
+
.summary { margin-bottom: 30px; border-left: 5px solid #4bc0c0; padding-left: 15px; }
|
|
34
|
+
</style>
|
|
35
|
+
</head>
|
|
36
|
+
<body>
|
|
37
|
+
<div class="container">
|
|
38
|
+
<h1>🚀 TypedJS vs TypeScript</h1>
|
|
39
|
+
<div class="summary">
|
|
40
|
+
<p><strong>Metric:</strong> Total turnaround time (Compilation + Execution) in <strong>milliseconds</strong>.</p>
|
|
41
|
+
<p>Lower is better. Results based on your local system benchmark.</p>
|
|
42
|
+
</div>
|
|
43
|
+
<canvas id="benchmarkChart"></canvas>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<script>
|
|
47
|
+
const ctx = document.getElementById('benchmarkChart').getContext('2d');
|
|
48
|
+
new Chart(ctx, {
|
|
49
|
+
type: 'bar',
|
|
50
|
+
data: {
|
|
51
|
+
labels: ${JSON.stringify(labels)},
|
|
52
|
+
datasets: [
|
|
53
|
+
{ label: 'TypedJS (Dev)', data: ${JSON.stringify(tjsDev)}, backgroundColor: '#ffce56' },
|
|
54
|
+
{ label: 'TypedJS (Prod)', data: ${JSON.stringify(tjsProd)}, backgroundColor: '#4bc0c0' },
|
|
55
|
+
{ label: 'TypeScript (Total)', data: ${JSON.stringify(tsTotal)}, backgroundColor: '#36a2eb' }
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
options: {
|
|
59
|
+
responsive: true,
|
|
60
|
+
scales: { y: { beginAtZero: true, title: { display: true, text: 'Time (ms)' } } },
|
|
61
|
+
plugins: {
|
|
62
|
+
title: { display: true, text: 'Developer Velocity: Save to Run Time' }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
</script>
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
fs.writeFileSync(path.join(__dirname, 'benchmark_report.html'), htmlTemplate);
|
|
72
|
+
console.log('✅ Visual report generated: benchmarks/benchmark_report.html');
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "Simple Benchmark",
|
|
4
|
+
"typedjs": {
|
|
5
|
+
"dev": {
|
|
6
|
+
"compileTime": "29.77ms",
|
|
7
|
+
"execTime": "8.79ms",
|
|
8
|
+
"totalTime": "38.56ms",
|
|
9
|
+
"success": true
|
|
10
|
+
},
|
|
11
|
+
"prod": {
|
|
12
|
+
"compileTime": "28.88ms",
|
|
13
|
+
"execTime": "8.30ms",
|
|
14
|
+
"totalTime": "37.18ms",
|
|
15
|
+
"success": true
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"typescript": {
|
|
19
|
+
"compileTime": "7474ms",
|
|
20
|
+
"execTime": "40ms",
|
|
21
|
+
"totalTime": "7514ms",
|
|
22
|
+
"tsSize": "777 bytes",
|
|
23
|
+
"jsSize": "556 bytes",
|
|
24
|
+
"success": true
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "Complex Benchmark",
|
|
29
|
+
"typedjs": {
|
|
30
|
+
"dev": {
|
|
31
|
+
"compileTime": "41.91ms",
|
|
32
|
+
"execTime": "99.21ms",
|
|
33
|
+
"totalTime": "141.12ms",
|
|
34
|
+
"success": true
|
|
35
|
+
},
|
|
36
|
+
"prod": {
|
|
37
|
+
"compileTime": "43.99ms",
|
|
38
|
+
"execTime": "91.41ms",
|
|
39
|
+
"totalTime": "135.39ms",
|
|
40
|
+
"success": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"typescript": {
|
|
44
|
+
"compileTime": "7660ms",
|
|
45
|
+
"execTime": "47ms",
|
|
46
|
+
"totalTime": "7707ms",
|
|
47
|
+
"tsSize": "2222 bytes",
|
|
48
|
+
"jsSize": "1629 bytes",
|
|
49
|
+
"success": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "Loop Benchmark (Torture Test)",
|
|
54
|
+
"typedjs": {
|
|
55
|
+
"dev": {
|
|
56
|
+
"compileTime": "21.96ms",
|
|
57
|
+
"execTime": "95.52ms",
|
|
58
|
+
"totalTime": "117.48ms",
|
|
59
|
+
"success": true
|
|
60
|
+
},
|
|
61
|
+
"prod": {
|
|
62
|
+
"compileTime": "21.87ms",
|
|
63
|
+
"execTime": "97.24ms",
|
|
64
|
+
"totalTime": "119.11ms",
|
|
65
|
+
"success": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"typescript": {
|
|
69
|
+
"compileTime": "7626ms",
|
|
70
|
+
"execTime": "43ms",
|
|
71
|
+
"totalTime": "7669ms",
|
|
72
|
+
"tsSize": "221 bytes",
|
|
73
|
+
"jsSize": "183 bytes",
|
|
74
|
+
"success": true
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
// Fix __dirname for ES modules
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
console.log('🚀 TypedJS vs TypeScript Benchmark\n');
|
|
11
|
+
console.log('='.repeat(60));
|
|
12
|
+
|
|
13
|
+
function benchmark(name, tjsFile, tsFile) {
|
|
14
|
+
console.log(`\n📊 Running: ${name}`);
|
|
15
|
+
console.log('-'.repeat(60));
|
|
16
|
+
|
|
17
|
+
const results = {
|
|
18
|
+
name,
|
|
19
|
+
typedjs: { dev: {}, prod: {} },
|
|
20
|
+
typescript: {}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Helper to run TypedJS and parse metrics
|
|
24
|
+
function runTypedJS(file, isProd) {
|
|
25
|
+
const flag = isProd ? '--prod' : '';
|
|
26
|
+
// Use --bench-meta to get internal timing metrics
|
|
27
|
+
const output = execSync(`node ../src/cli.js ${file} ${flag} --bench-meta`, {
|
|
28
|
+
encoding: 'utf-8',
|
|
29
|
+
cwd: __dirname
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const benchMatch = output.match(/__BENCH__(\{.*\})/);
|
|
33
|
+
let metrics = {};
|
|
34
|
+
if (benchMatch) {
|
|
35
|
+
metrics = JSON.parse(benchMatch[1]);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
compileTime: metrics.compileTime ? `${metrics.compileTime.toFixed(2)}ms` : '?',
|
|
40
|
+
execTime: metrics.execTime ? `${metrics.execTime.toFixed(2)}ms` : '?',
|
|
41
|
+
totalTime: metrics.compileTime && metrics.execTime ? `${(metrics.compileTime + metrics.execTime).toFixed(2)}ms` : '?'
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Benchmark TypedJS Dev Mode
|
|
46
|
+
try {
|
|
47
|
+
console.log('⏱️ TypedJS (Dev Mode)...');
|
|
48
|
+
const m = runTypedJS(tjsFile, false);
|
|
49
|
+
|
|
50
|
+
results.typedjs.dev = {
|
|
51
|
+
...m,
|
|
52
|
+
success: true
|
|
53
|
+
};
|
|
54
|
+
console.log(` ✅ Compiled in ${m.compileTime}, executed in ${m.execTime} (total: ${m.totalTime})`);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
results.typedjs.dev = { success: false, error: err.message };
|
|
57
|
+
console.log(` ❌ Failed: ${err.message}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Benchmark TypedJS Prod Mode
|
|
61
|
+
try {
|
|
62
|
+
console.log('⏱️ TypedJS (Prod Mode)...');
|
|
63
|
+
const m = runTypedJS(tjsFile, true);
|
|
64
|
+
|
|
65
|
+
results.typedjs.prod = {
|
|
66
|
+
...m,
|
|
67
|
+
success: true
|
|
68
|
+
};
|
|
69
|
+
console.log(` ✅ Compiled in ${m.compileTime}, executed in ${m.execTime} (total: ${m.totalTime})`);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
results.typedjs.prod = { success: false, error: err.message };
|
|
72
|
+
console.log(` ❌ Failed: ${err.message}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Benchmark TypeScript
|
|
76
|
+
try {
|
|
77
|
+
console.log('⏱️ TypeScript...');
|
|
78
|
+
const jsFile = tsFile.replace('.ts', '.js');
|
|
79
|
+
|
|
80
|
+
// Compile
|
|
81
|
+
const compileStart = Date.now();
|
|
82
|
+
execSync(`npx tsc ${tsFile} --target ES2020 --module ES2020 --moduleResolution node --esModuleInterop --lib ES2020,DOM`, {
|
|
83
|
+
cwd: __dirname,
|
|
84
|
+
stdio: 'pipe'
|
|
85
|
+
});
|
|
86
|
+
const compileTime = Date.now() - compileStart;
|
|
87
|
+
|
|
88
|
+
// Execute
|
|
89
|
+
const execStart = Date.now();
|
|
90
|
+
execSync(`node ${jsFile}`, {
|
|
91
|
+
encoding: 'utf-8',
|
|
92
|
+
cwd: __dirname
|
|
93
|
+
});
|
|
94
|
+
const execTime = Date.now() - execStart;
|
|
95
|
+
const totalTime = compileTime + execTime;
|
|
96
|
+
|
|
97
|
+
// Get file sizes
|
|
98
|
+
const tsSize = fs.statSync(path.join(__dirname, tsFile)).size;
|
|
99
|
+
const jsSize = fs.statSync(path.join(__dirname, jsFile)).size;
|
|
100
|
+
|
|
101
|
+
results.typescript = {
|
|
102
|
+
compileTime: `${compileTime}ms`,
|
|
103
|
+
execTime: `${execTime}ms`,
|
|
104
|
+
totalTime: `${totalTime}ms`,
|
|
105
|
+
tsSize: `${tsSize} bytes`,
|
|
106
|
+
jsSize: `${jsSize} bytes`,
|
|
107
|
+
success: true
|
|
108
|
+
};
|
|
109
|
+
console.log(` ✅ Compiled in ${compileTime}ms, executed in ${execTime}ms (total: ${totalTime}ms)`);
|
|
110
|
+
|
|
111
|
+
// Cleanup
|
|
112
|
+
if (fs.existsSync(path.join(__dirname, jsFile))) {
|
|
113
|
+
fs.unlinkSync(path.join(__dirname, jsFile));
|
|
114
|
+
}
|
|
115
|
+
} catch (err) {
|
|
116
|
+
results.typescript = { success: false, error: err.message };
|
|
117
|
+
const errorDetails = err.stdout ? err.stdout.toString() : (err.stderr ? err.stderr.toString() : err.message);
|
|
118
|
+
console.log(` ❌ Failed: ${errorDetails.trim()}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return results;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Run benchmarks
|
|
125
|
+
const results = [];
|
|
126
|
+
|
|
127
|
+
results.push(benchmark('Simple Benchmark', 'simple.tjs', 'simple.ts'));
|
|
128
|
+
results.push(benchmark('Complex Benchmark', 'complex.tjs', 'complex.ts'));
|
|
129
|
+
results.push(benchmark('Loop Benchmark (Torture Test)', 'loop.tjs', 'loop.ts'));
|
|
130
|
+
|
|
131
|
+
// Summary
|
|
132
|
+
console.log('\n' + '='.repeat(60));
|
|
133
|
+
console.log('📈 RESULTS SUMMARY');
|
|
134
|
+
console.log('='.repeat(60));
|
|
135
|
+
|
|
136
|
+
results.forEach(result => {
|
|
137
|
+
console.log(`\n${result.name}:`);
|
|
138
|
+
if (result.typedjs && result.typedjs.dev && result.typedjs.dev.success) {
|
|
139
|
+
console.log(` TypedJS Dev: ${result.typedjs.dev.totalTime} (compile: ${result.typedjs.dev.compileTime}, exec: ${result.typedjs.dev.execTime})`);
|
|
140
|
+
}
|
|
141
|
+
if (result.typedjs && result.typedjs.prod && result.typedjs.prod.success) {
|
|
142
|
+
console.log(` TypedJS Prod: ${result.typedjs.prod.totalTime} (compile: ${result.typedjs.prod.compileTime}, exec: ${result.typedjs.prod.execTime})`);
|
|
143
|
+
}
|
|
144
|
+
if (result.typescript && result.typescript.success) {
|
|
145
|
+
console.log(` TypeScript: ${result.typescript.totalTime} (compile: ${result.typescript.compileTime}, exec: ${result.typescript.execTime})`);
|
|
146
|
+
} else if (result.typescript && !result.typescript.success) {
|
|
147
|
+
console.log(` TypeScript: Failed`);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
console.log('\n' + '='.repeat(60));
|
|
152
|
+
console.log('✨ Benchmark complete!\n');
|
|
153
|
+
|
|
154
|
+
// Save results
|
|
155
|
+
fs.writeFileSync(
|
|
156
|
+
path.join(__dirname, 'results.json'),
|
|
157
|
+
JSON.stringify(results, null, 2)
|
|
158
|
+
);
|
|
159
|
+
console.log('📝 Results saved to benchmarks/results.json');
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Simple benchmark - basic types and functions
|
|
2
|
+
interface User {
|
|
3
|
+
id: number;
|
|
4
|
+
name: string;
|
|
5
|
+
email: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function createUser(id: number, name: string, email: string): User {
|
|
9
|
+
return { id, name, email };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function calculateTotal(prices: Array<number>): number {
|
|
13
|
+
let total: number = 0;
|
|
14
|
+
for (let i: number = 0; i < prices.length; i++) {
|
|
15
|
+
total = total + prices[i];
|
|
16
|
+
}
|
|
17
|
+
return total;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Run benchmark
|
|
21
|
+
let users: Array<User> = [];
|
|
22
|
+
for (let i: number = 0; i < 1000; i++) {
|
|
23
|
+
let user: User = createUser(i, "User" + i, "user" + i + "@test.com");
|
|
24
|
+
users.push(user);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let prices: Array<number> = [10, 20, 30, 40, 50];
|
|
28
|
+
let total: number = calculateTotal(prices);
|
|
29
|
+
|
|
30
|
+
console.log("Created", users.length, "users");
|
|
31
|
+
console.log("Total price:", total);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Simple benchmark - basic types and functions
|
|
2
|
+
interface User {
|
|
3
|
+
id: number;
|
|
4
|
+
name: string;
|
|
5
|
+
email: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function createUser(id: number, name: string, email: string): User {
|
|
9
|
+
return { id, name, email };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function calculateTotal(prices: Array<number>): number {
|
|
13
|
+
let total: number = 0;
|
|
14
|
+
for (let i: number = 0; i < prices.length; i++) {
|
|
15
|
+
total = total + prices[i];
|
|
16
|
+
}
|
|
17
|
+
return total;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Run benchmark
|
|
21
|
+
let users: Array<User> = [];
|
|
22
|
+
for (let i: number = 0; i < 1000; i++) {
|
|
23
|
+
let user: User = createUser(i, "User" + i, "user" + i + "@test.com");
|
|
24
|
+
users.push(user);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let prices: Array<number> = [10, 20, 30, 40, 50];
|
|
28
|
+
let total: number = calculateTotal(prices);
|
|
29
|
+
|
|
30
|
+
console.log("Created", users.length, "users");
|
|
31
|
+
console.log("Total price:", total);
|
|
32
|
+
|
|
33
|
+
export {};
|