8000 Test 4.6/2: finished · JayAyAre/PyScript-vs-JavaScript@a59a3a8 · GitHub
[go: up one dir, main page]

Skip to content

Commit a59a3a8

Browse files
committed
Test 4.6/2: finished
1 parent 9c65c60 commit a59a3a8

File tree

12 files changed

+564
-0
lines changed

12 files changed

+564
-0
lines changed

4.6-patrones/prueba-2/.rnd

1 KB
Binary file not shown.

4.6-patrones/prueba-2/cert.pem

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDRzCCAi+gAwIBAgIJANMj6R5DLofFMA0GCSqGSIb3DQEBBQUAMDoxCzAJBgNV
3+
BAYTAkVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxFzAVBgNVBAoTDk15IENvbXBhbnkg
4+
THRkMB4XDTI1MDQxODEzNDc1NVoXDTI2MDQxODEzNDc1NVowOjELMAkGA1UEBhMC
5+
RVMxEjAQBgNVBAgTCUJlcmtzaGlyZTEXMBUGA1UEChMOTXkgQ29tcGFueSBMdGQw
6+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDB7w5U3dNVAZ9HgAbIvGUr
7+
O7NxfugrW3ZX03NyxJfqbA3GQBmLZv3Y139xXoVd39CpLu0REYl8St+b7nHEBA8g
8+
FdKZgCwyuI2PcN4Ewk+DZ9QUxjOVuj6bfsyOijNc7VJ35i4NH+Wj/t6079MJmn96
9+
DeRHhFFe+io6j8TfNXIblam8p2t03A2qAjsZRuXLkclZ5E7FJhVKEWnU6Wll7oI5
10+
9kqN8EmzWuV2RvGnFOvjR6QDaONAX8tMGC9cfvqE6HJ6zLX5FikLEUj3dSPDj8Wt
11+
QIelTuxBFK7CPoaNmconWIx2t3b7crvZ4Zxa+BHfwmuxorBpy+HIHgFZTddo1jL9
12+
AgMBAAGjUDBOMB0GA1UdDgQWBBSjaGpisyeSNA0aYM6eEVVzp2tsTTAfBgNVHSME
13+
GDAWgBSjaGpisyeSNA0aYM6eEVVzp2tsTTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
14+
DQEBBQUAA4IBAQC5thww0G4R9wPampj/9CrtEku4EHgapuT7gMt3iQ0imUEUBh3g
15+
6PEkOAt4kukIc6V/8+p+kX2g+eXdTvOmNuWxjKofRXvt7C148rgvvTuah74AJtfU
16+
95untquyzGpVi/LAN3xMspqULM6ICXo27cKaFv38vYHLLDNKM7So+KCAQ/O8jtZn
17+
wJGN/t/MerPTRDFBhEkNzz4n2pUvvVOd9ccRbnTL2Ux89hbL9wgo7E372NAyJmRz
18+
ZqKIu+S63hSfck9HepM+dNvlf85edgvOzjB5hp1g1MJrFTDYYzZi2RE+tG+KRRVP
19+
pntJ1xn1GCZ2ShbpoXZPn54FtmtgAVIF/EDK
20+
-----END CERTIFICATE-----

4.6-patrones/prueba-2/index.html

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Benchmarking: JavaScript vs PyScript</title>
7+
<script type="importmap">
8+
{
9+
"imports": {
10+
"ml-random-forest": "https://cdn.jsdelivr.net/npm/ml-random-forest@2.1.0/dist/random-forest.js"
11+
}
12+
}
13+
</script>
14+
15+
<script type="module" src="javascript/main.js"></script>
16+
17+
<!-- 3) Psist Script Core -->
18+
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
19+
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
20+
21+
<script>
22+
async function fetchMNIST() {
23+
try {
24+
const response = await fetch('https://cdn.jsdelivr.net/gh/mnielsen/neural-networks-and-deep-learning@master/data/mnist.pkl.gz');
25+
if (!response.ok) throw new Error('Error en la descarga');
26+
const buffer = await response.arrayBuffer();
27+
console.log('MNIST descargado');
28+
return buffer; // 🔥 ESTA LÍNEA ES CLAVE
29+
} catch (error) {
30+
console.error('Error cargando MNIST:', error);
31+
throw error;
32+
}
33+
}
34+
35+
</script>
36+
<script>
37+
if (!crypto.randomUUID) {
38+
crypto.randomUUID = function() {
39+
// Genera un UUID v4
40+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
41+
const r = Math.random() * 16 | 0;
42+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
43+
return v.toString(16);
44+
});
45+
}
46+
}
47+
document.addEventListener('py:ready', () => {
48+
document.getElementById("run-button-py").disabled = false;
49+
50+
document.getElementById("run-button-py").textContent = 'Run in PyScript';
51+
console.log('PyScript fully loaded');
52+
});
53+
let pyTimer = null;
54+
let pyStartTime = 0;
55+
56+
function startPyTimer() {
57+
pyStartTime = performance.now();
58+
const timerElement = document.getElementById("py-timer-display");
59+
60+
function updateTimer() {
61+
if (!pyTimer) return;
62+
63+
const elapsedMs = performance.now() - pyStartTime;
64+
const elapsed = (elapsedMs / 1000).toFixed(3);
65+
timerElement.textContent = `PyScript Timer: ${elapsed} s`;
66+
67+
pyTimer = requestAnimationFrame(updateTimer);
68+
}
69+
70+
cancelAnimationFrame(pyTimer);
71+
pyTimer = requestAnimationFrame(updateTimer);
72+
}
73+
74+
function stopPyTimer() {
75+
cancelAnimationFrame(pyTimer);
76+
pyTimer = null;
77+
78+
const elapsedMs = performance.now() - pyStartTime;
79+
const elapsed = (elapsedMs / 1000).toFixed(3);
80+
document.getElementById("py-timer-display").textContent = `PyScript Timer: ${elapsed} s`;
81+
}
82+
let startTime = performance.now();
83+
84+
document.addEventListener('py:ready', () => {
85+
let endTime = performance.now();
86+
let loadTime = endTime - startTime;
87+
document.getElementById("output").innerText += `PLT: ${loadTime.toFixed(2)} ms`;
88+
});
89+
90+
function clearCell(elementId) {
91+
const operations = ["worker", "training", "inference", "accuracy", "memory", "total"];
92+
operations.forEach(op => {
93+
const element = document.getElementById(`${elementId}-${op}`);
94+
if (element) {
95+
element.innerHTML = "";
96+
}
97+
});
98+
}
99+
</script>
100+
101+
<body>
102+
<script type="py" src="python/main.py" config="json/pyscript-main.json"></script>
103+
<script>
104+
function clearMetrics(prefix) {
105+
["worker","training","inference","accuracy","memory","total"]
106+
.forEach(id => document.getElementById(`${prefix}-${id}`).textContent = "");
107+
}
108+
</script>
109+
<h1>Benchmark: cryptographic proofs</h1>
110+
<h2 id="output"></h2>
111+
112+
<div>
113+
<label>Repetitions:</label>
114+
<input type="number" id="num-repetitions-js" value="5" min="1">
115+
<button id="run-button-js" onclick="javascriptBenchmark()">Run JavaScript</button>
116+
</div>
117+
118+
119+
<div>
120+
<label>Repetitions:</label>
121+
<input type="number" id="num-repetitions-py" value="5" min="1">
122+
<button id="run-button-py" py-click="launch_worker" disabled>Run PyScript (Loading...)</button>
123+
</div>
124+
125+
126+
<h2 id="js-timer-display">JS Timer: 0.00 s</h2>
127+
<h2 id="py-timer-display">PyScript Timer: 0.00 s</h2>
128+
<div id="debug-console"></div>
129+
130+
131+
<table id="metrics-container">
132+
<thead>
133+
<tr>
134+
<th>Metric</th><th>JavaScript</th><th>PyScript</th>
135+
</tr>
136+
</thead>
137+
<tbody>
138+
<tr>
139+
<td>Worker init</td>
140+
<td id="javascript-worker"></td>
141+
<td id="pyscript-worker"></td>
142+
</tr>
143+
<tr>
144+
<td>Av. Training time</td>
145+
<td id="javascript-training"></td>
146+
<td id="pyscript-training"></td>
147+
</tr>
148+
<tr>
149+
<td>Av. Inference time</td>
150+
<td id="javascript-inference"></td>
151+
<td id="pyscript-inference"></td>
152+
</tr>
153+
<tr>
154+
<td>Av. Accuracy</td>
155+
<td id="javascript-accuracy"></td>
156+
<td id="pyscript-accuracy"></td>
157+
</tr>
158+
<tr>
159+
<td>Model size</td>
160+
<td id="javascript-memory"></td>
161+
<td id="pyscript-memory"></td>
162+
</tr>
163+
<tr>
164+
<td>Total time</td>
165+
<td id="javascript-total"></td>
166+
<td id="pyscript-total"></td>
167+
</tr>
168+
</tbody>
169+
</table>
170+
</body>
171+
</html>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
(() => {
2+
let worker = null;
3+
let jsTimer = null;
4+
let jsStartTime = 0;
5+
6+
function startJsTimer() {
7+
jsStartTime = performance.now();
8+
const timerElement = document.getElementById("js-timer-display");
9+
function updateTimer() {
10+
if (!jsTimer) return;
11+
const elapsed = ((performance.now() - jsStartTime) / 1000).toFixed(
12+
3
13+
);
14+
timerElement &&
15+
(timerElement.textContent = `JS Timer: ${elapsed} s`);
16+
jsTimer = requestAnimationFrame(updateTimer);
17+
}
18+
cancelAnimationFrame(jsTimer);
19+
jsTimer = requestAnimationFrame(updateTimer);
20+
}
21+
22+
function stopJsTimer() {
23+
cancelAnimationFrame(jsTimer);
24+
jsTimer = null;
25+
const elapsed = ((performance.now() - jsStartTime) / 1000).toFixed(3);
26+
const timerElement = document.getElementById("js-timer-display");
27+
timerElement && (timerElement.textContent = `JS Timer: ${elapsed} s`);
28+
}
29+
30+
function setText(id, text) {
31+
const el = document.getElementById(id);
32+
if (el) el.textContent = text;
33+
else console.warn(`Element with id \"${id}\" not found`);
34+
}
35+
36+
function clearMetrics(prefix) {
37+
[
38+
"worker",
39+
"training",
40+
"inference",
41+
"accuracy",
42+
"memory",
43+
"total",
44+
].forEach((id) => {
45+
setText(`${prefix}-${id}`, "");
46+
});
47+
}
48+
49+
async function javascriptBenchmark() {
50+
const outputEl = document.getElementById("javascript-output");
51+
try {
52+
outputEl && (outputEl.textContent = "");
53+
startJsTimer();
54+
clearMetrics("javascript");
55+
56+
const startWorkerTime = performance.now();
57+
if (!worker) {
58+
worker = new Worker(new URL("worker.js", import.meta.url), {
59+
type: "module",
60+
});
61+
}
62+
const workerTime = performance.now() - startWorkerTime;
63+
setText("javascript-worker", `${workerTime.toFixed(2)} ms`);
64+
65+
const repetitions = parseInt(
66+
document.getElementById("num-repetitions-js")?.value || "1",
67+
10
68+
);
69+
const id = `js-${Date.now()}`;
70+
71+
const resultJson = await new Promise((resolve, reject) => {
72+
function onMessage(e) {
73+
if (e.data.id !== id) return;
74+
worker.removeEventListener("message", onMessage);
75+
if (e.data.error) reject(new Error(e.data.error));
76+
else {
77+
console.log("Mensaje recibido del worker:", e.data);
78+
resolve(e.data.json);
79+
}
80+
}
81+
worker.addEventListener("message", onMessage);
82+
worker.postMessage({
83+
id,
84+
type: "js_run_js_benchmark",
85+
repetitions,
86+
});
87+
});
88+
89+
const r = JSON.parse(resultJson);
90+
displayResult(r);
91+
} catch (err) {
92+
console.error("Benchmark error:", err);
93+
outputEl && (outputEl.textContent = `Error: ${err.message}`);
94+
} finally {
95+
stopJsTimer();
96+
}
97+
}
98+
99+
function displayResult(r) {
100+
setText("javascript-training", `${r.training_time_ms.toFixed(2)} ms`);
101+
setText("javascript-inference", `${r.inference_time_ms.toFixed(2)} ms`);
102+
setText("javascript-accuracy", `${r.accuracy.toFixed(2)} %`);
103+
setText("javascript-memory", `${r.model_size_mb.toFixed(2)} MB`);
104+
setText("javascript-total", `${r.overall_time_ms.toFixed(2)} ms`);
105+
}
106+
107+
document.addEventListener("DOMContentLoaded", () => {
108+
const btn = document.getElementById("run-button-js");
109+
if (btn) btn.addEventListener("click", javascriptBenchmark);
110+
});
111+
112+
window.javascriptBenchmark = javascriptBenchmark;
113+
})();
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import KNN from "https://cdn.skypack.dev/ml-knn";
2+
3+
self.addEventListener("message", async (e) => {
4+
const { id, type, workerTime, repetitions } = e.data;
5+
if (type !== "js_run_js_benchmark") return;
6+
7+
const DIGITS_URL = "/json/digits.json";
8+
const resp = await fetch(DIGITS_URL);
9+
const { data, target } = await resp.json();
10+
11+
function trainTestSplit(X, y, testRatio = 0.3) {
12+
const indices = [...X.keys()];
13+
for (let i = indices.length - 1; i > 0; i--) {
14+
const j = Math.floor(Math.random() * (i + 1));
15+
[indices[i], indices[j]] = [indices[j], indices[i]];
16+
}
17+
const testCount = Math.floor(X.length * testRatio);
18+
const testIdx = indices.slice(0, testCount);
19+
const trainIdx = indices.slice(testCount);
20+
21+
const X_train = trainIdx.map((i) => X[i]);
22+
const y_train = trainIdx.map((i) => y[i]);
23+
const X_test = testIdx.map((i) => X[i]);
24+
const y_test = testIdx.map((i) => y[i]);
25+
26+
return { X_train, y_train, X_test, y_test };
27+
}
28+
29+
let totalTrain = 0,
30+
totalInfer = 0,
31+
totalAcc = 0,
32+
model;
33+
34+
const t0All = performance.now();
35+
36+
for (let i = 0; i < repetitions; i++) {
37+
const { X_train, y_train, X_test, y_test } = trainTestSplit(
38+
data,
39+
target
40+
);
41+
42+
const t0 = performance.now();
43+
model = new KNN(X_train, y_train, { k: 3 });
44+
totalTrain += performance.now() - t0;
45+
46+
const t1 = performance.now();
47+
const preds = model.predict(X_test);
48+
totalInfer += performance.now() - t1;
49+
50+
const correct = preds.reduce(
51+
(sum, p, idx) => sum + (p === y_test[idx] ? 1 : 0),
52+
0
53+
);
54+
totalAcc += (correct / y_test.length) * 100;
55+
}
56+
57+
const overall = performance.now() - t0All;
58+
59+
const modelJson = JSON.stringify(model.toJSON());
60+
const modelSizeMB = new Blob([modelJson]).size / 1024 ** 2;
61+
62+
const result = {
63+
training_time_ms: totalTrain / repetitions,
64+
inference_time_ms: totalInfer / repetitions,
65+
accuracy: totalAcc / repetitions,
66+
model_size_mb: modelSizeMB,
67+
overall_time_ms: overall,
68+
};
69+
70+
self.postMessage({ id, json: JSON.stringify(result) });
71+
});

4.6-patrones/prueba-2/json/digits.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"files": {
3+
"/python/worker.py": "worker.py"
4+
}
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"packages": ["scikit-learn"]
3+
}

0 commit comments

Comments
 (0)
0