Skip to content

Commit 7b6a192

Browse files
committed
becm
1 parent 4aa2e7e commit 7b6a192

File tree

4 files changed

+62
-64
lines changed

4 files changed

+62
-64
lines changed

benchmark-result.png

26.2 KB
Loading

bun-mastica-historial/benchmark.js

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,33 @@
1-
function generateLogs(n) {
2-
const logs = [];
1+
// Función generadora que "cede" un log a la vez, sin crear un array.
2+
function* generateLogsStream(n) {
33
const start = Date.now() - 7 * 24 * 60 * 60 * 1000; // 7 días atrás
44
for (let i = 0; i < n; i++) {
5-
logs.push({
6-
timestamp: start + i * 60000, // 1 log por minuto
5+
// 'yield' entrega el objeto y pausa la función hasta la siguiente iteración del bucle que lo consume.
6+
yield {
7+
timestamp: start + i * 60000,
78
value: Math.random() * 100,
8-
userId: Math.floor(Math.random() * 1000), // Simula 1000 usuarios
9-
action: Math.random() > 0.5 ? 'click' : 'view', // Simula dos tipos de acciones
10-
temperature: Math.random() * 30 + 15, // Temperatura entre 15 y 45 grados
11-
temperature2: Math.random() * 30 + 15, // Temperatura entre 15 y 45 grados
12-
name: `User${Math.floor(Math.random() * 1000)}`, // Nombre de usuario simulado
13-
surname: `Surname${Math.floor(Math.random() * 1000)}`, // Apellido de usuario simulado
14-
email: `user${Math.floor(Math.random() * 1000)}@example.com`, // Email simulado
15-
});
9+
// Los otros campos no son necesarios para el cálculo, así que podemos omitirlos
10+
// para que la generación sea aún más rápida en ambos lenguajes.
11+
// Si los necesitaras, los añadirías aquí.
12+
};
1613
}
17-
return logs;
1814
}
1915

20-
function benchmark() {
21-
const logs = generateLogs(50000000);
16+
function benchmarkOptimized() {
17+
const n = 50000000;
2218
const interval = 10 * 60 * 1000; // 10 minutos en ms
2319

20+
console.log("Iniciando benchmark optimizado de Node.js/Bun...");
2421
const start = performance.now();
2522

2623
const grouped = {};
27-
for (const log of logs) {
24+
25+
// Creamos el generador. No se ejecuta nada todavía.
26+
const logGenerator = generateLogsStream(n);
27+
28+
// El bucle 'for...of' consumirá el generador, pidiendo un log a la vez.
29+
// ¡No se almacena ningún array de 50 millones de logs!
30+
for (const log of logGenerator) {
2831
const bucket = Math.floor(log.timestamp / interval) * interval;
2932
if (!grouped[bucket]) {
3033
grouped[bucket] = { sum: 0, count: 0 };
@@ -36,8 +39,8 @@ function benchmark() {
3639
const averages = Object.values(grouped).map(g => g.sum / g.count);
3740

3841
const end = performance.now();
39-
console.log(`Bun JS - Tiempo: ${((end - start) / 1000).toFixed(2)} s`);
42+
console.log(`Bun/Node JS (Optimizado) - Tiempo: ${((end - start) / 1000).toFixed(3)} s`);
4043
console.log(`Buckets calculados: ${averages.length}`);
4144
}
4245

43-
benchmark();
46+
benchmarkOptimized();

dotnet-mastica-historial/Program.cs

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,66 +7,44 @@ class Program
77
{
88
static void Main()
99
{
10-
var logs = GenerateLogs(50000000);
10+
int n = 50000000;
1111
var interval = TimeSpan.FromMinutes(10);
12-
1312
var sw = Stopwatch.StartNew();
1413

15-
var grouped = new Dictionary<long, (double sum, int count)>();
16-
17-
foreach (var log in logs)
18-
{
19-
var bucket = (long)(log.Timestamp.Ticks / interval.Ticks) * interval.Ticks;
20-
if (!grouped.ContainsKey(bucket))
21-
{
22-
grouped[bucket] = (0, 0);
23-
}
24-
var current = grouped[bucket];
25-
grouped[bucket] = (current.sum + log.Value, current.count + 1);
26-
}
27-
28-
var averages = grouped.Values.Select(g => g.sum / g.count).ToList();
14+
// Procesa los datos "al vuelo" sin almacenarlos en una lista
15+
var averages = ProcessLogsOnTheFly(n, interval);
2916

3017
sw.Stop();
31-
Console.WriteLine($"C# .NET - Tiempo: {sw.Elapsed.TotalSeconds:F3} s");
18+
Console.WriteLine($"C# .NET (Optimizado) - Tiempo: {sw.Elapsed.TotalSeconds:F3} s");
3219
Console.WriteLine($"Buckets calculados: {averages.Count}");
3320
}
3421

35-
static List<Log> GenerateLogs(int n)
22+
static List<double> ProcessLogsOnTheFly(int n, TimeSpan interval)
3623
{
37-
var logs = new List<Log>(n);
24+
var grouped = new Dictionary<long, (double sum, int count)>();
3825
var start = DateTime.Now.AddDays(-7);
3926
var rnd = new Random();
4027

28+
// No creamos una lista gigante. Generamos y procesamos en el mismo bucle.
4129
for (int i = 0; i < n; i++)
4230
{
43-
logs.Add(new Log
31+
// Genera solo los datos que necesitas para esta iteración
32+
var timestamp = start.AddMinutes(i);
33+
var value = rnd.NextDouble() * 100;
34+
35+
// El resto de la lógica de procesamiento es idéntica
36+
var bucket = (long)(timestamp.Ticks / interval.Ticks) * interval.Ticks;
37+
38+
// Usamos TryGetValue para ser un poco más eficientes que ContainsKey + indexer
39+
if (!grouped.TryGetValue(bucket, out var current))
4440
{
45-
Timestamp = start.AddMinutes(i),
46-
Value = rnd.NextDouble() * 100,
47-
UserId = rnd.Next(0, 1000),
48-
Action = rnd.NextDouble() > 0.5 ? "click" : "view",
49-
Temperature = rnd.NextDouble() * 30 + 15,
50-
Temperature2 = rnd.NextDouble() * 30 + 15,
51-
Name = $"User{rnd.Next(0,1000)}",
52-
Surname = $"Surname{rnd.Next(0,1000)}",
53-
Email = $"user{rnd.Next(0,1000)}@example.com"
54-
});
41+
current = (0, 0);
42+
}
43+
44+
grouped[bucket] = (current.sum + value, current.count + 1);
5545
}
5646

57-
return logs;
47+
// El cálculo final es el mismo
48+
return grouped.Values.Select(g => g.sum / g.count).ToList();
5849
}
59-
}
60-
61-
class Log
62-
{
63-
public DateTime Timestamp { get; set; }
64-
public double Value { get; set; }
65-
public int UserId { get; set; }
66-
public string Action { get; set; } = "";
67-
public double Temperature { get; set; }
68-
public double Temperature2 { get; set; }
69-
public string Name { get; set; } = "";
70-
public string Surname { get; set; } = "";
71-
public string Email { get; set; } = "";
72-
}
50+
}

readme.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,21 @@ C# .NET - Tiempo: 7,123 s
1919
Buckets calculados: 5000000
2020
PS C:\Users\frtri\Documents\benchmarksMiiot\miiot-benchmarks> bun run .\bun-mastica-historial\benchmark.js
2121
Bun JS - Tiempo: 11.40 s
22-
Buckets calculados: 5000001
22+
Buckets calculados: 5000001
23+
24+
25+
OPTIMIZADO POR QUE NO CABE EN LA MEMORIA Y LO CORTABA EL GARBACE COLLECTOR DE .NET
26+
27+
PS C:\Users\frtri\Documents\benchmarksMiiot\miiot-benchmarks> bun run .\bun-mastica-historial\benchmark.js
28+
Iniciando benchmark optimizado de Node.js/Bun...
29+
Bun/Node JS (Optimizado) - Tiempo: 8.083 s
30+
Buckets calculados: 5000001
31+
PS C:\Users\frtri\Documents\benchmarksMiiot\miiot-benchmarks> dotnet run --project .\dotnet-mastica-historial\dotnet-mastica-historial.csproj
32+
C# .NET (Optimizado) - Tiempo: 2,168 s
33+
Buckets calculados: 5000001
34+
PS C:\Users\frtri\Documents\benchmarksMiiot\miiot-benchmarks> node .\bun-mastica-historial\benchmark.js
35+
Iniciando benchmark optimizado de Node.js/Bun...
36+
Bun/Node JS (Optimizado) - Tiempo: 19.884 s
37+
Buckets calculados: 5000001
38+
39+
![Resultados del benchmark](benchmark-result.png)

0 commit comments

Comments
 (0)