@@ -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+ }
0 commit comments