1+ using System ;
2+ using System . Diagnostics ;
3+ using System . Linq ;
4+ using System . Threading ;
5+ using System . Threading . Tasks ;
6+ using EnumerableAsyncProcessor . Builders ;
7+
8+ namespace EnumerableAsyncProcessor . UnitTests ;
9+
10+ public class ParallelPerformanceTests
11+ {
12+ [ Test ]
13+ public async Task MeasureParallelProcessingTime_10000ItemsWith1SecondDelay ( )
14+ {
15+ const int itemCount = 10000 ;
16+ const int delaySeconds = 1 ;
17+
18+ var stopwatch = Stopwatch . StartNew ( ) ;
19+
20+ var processor = AsyncProcessorBuilder
21+ . WithItems ( Enumerable . Range ( 0 , itemCount ) )
22+ . ForEachAsync ( _ => Task . Delay ( TimeSpan . FromSeconds ( delaySeconds ) ) )
23+ . ProcessInParallel ( ) ;
24+
25+ await processor ;
26+
27+ stopwatch . Stop ( ) ;
28+
29+ var completedTasks = processor . GetEnumerableTasks ( ) . Count ( x => x . IsCompleted ) ;
30+
31+ await Assert . That ( completedTasks ) . IsEqualTo ( itemCount ) ;
32+
33+ Console . WriteLine ( $ "Total execution time: { stopwatch . Elapsed } ") ;
34+ Console . WriteLine ( $ "Total execution time (seconds): { stopwatch . Elapsed . TotalSeconds : F2} ") ;
35+ Console . WriteLine ( $ "Total execution time (milliseconds): { stopwatch . Elapsed . TotalMilliseconds : F0} ") ;
36+
37+ var expectedSequentialTime = itemCount * delaySeconds ;
38+ Console . WriteLine ( $ "Expected sequential time: { expectedSequentialTime : N0} seconds") ;
39+ Console . WriteLine ( $ "Speedup factor: { expectedSequentialTime / stopwatch . Elapsed . TotalSeconds : F2} x") ;
40+
41+ await Assert . That ( stopwatch . Elapsed . TotalSeconds ) . IsLessThan ( 10 ) ;
42+ }
43+
44+ [ Test ]
45+ public async Task MeasureParallelProcessingTime_1000ItemsWith100msDelay ( )
46+ {
47+ const int itemCount = 1000 ;
48+ const int delayMilliseconds = 100 ;
49+
50+ var stopwatch = Stopwatch . StartNew ( ) ;
51+
52+ var processor = AsyncProcessorBuilder
53+ . WithItems ( Enumerable . Range ( 0 , itemCount ) )
54+ . ForEachAsync ( _ => Task . Delay ( delayMilliseconds ) )
55+ . ProcessInParallel ( ) ;
56+
57+ await processor ;
58+
59+ stopwatch . Stop ( ) ;
60+
61+ var completedTasks = processor . GetEnumerableTasks ( ) . Count ( x => x . IsCompleted ) ;
62+
63+ await Assert . That ( completedTasks ) . IsEqualTo ( itemCount ) ;
64+
65+ Console . WriteLine ( $ "Total execution time: { stopwatch . Elapsed } ") ;
66+ Console . WriteLine ( $ "Total execution time (seconds): { stopwatch . Elapsed . TotalSeconds : F2} ") ;
67+ Console . WriteLine ( $ "Total execution time (milliseconds): { stopwatch . Elapsed . TotalMilliseconds : F0} ") ;
68+
69+ var expectedSequentialTimeMs = itemCount * delayMilliseconds ;
70+ Console . WriteLine ( $ "Expected sequential time: { expectedSequentialTimeMs : N0} milliseconds ({ expectedSequentialTimeMs / 1000.0 : F1} seconds)") ;
71+ Console . WriteLine ( $ "Speedup factor: { expectedSequentialTimeMs / stopwatch . Elapsed . TotalMilliseconds : F2} x") ;
72+
73+ await Assert . That ( stopwatch . Elapsed . TotalSeconds ) . IsLessThan ( 10 ) ;
74+ }
75+
76+ [ Test ]
77+ public async Task MeasureParallelProcessingTime_1000ItemsWithThreadSleep ( )
78+ {
79+ const int itemCount = 1000 ;
80+ const int sleepMilliseconds = 100 ;
81+
82+ var stopwatch = Stopwatch . StartNew ( ) ;
83+
84+ var processor = AsyncProcessorBuilder
85+ . WithItems ( Enumerable . Range ( 0 , itemCount ) )
86+ . ForEachAsync ( _ => Task . Run ( ( ) => Thread . Sleep ( sleepMilliseconds ) ) )
87+ . ProcessInParallel ( ) ;
88+
89+ await processor ;
90+
91+ stopwatch . Stop ( ) ;
92+
93+ var completedTasks = processor . GetEnumerableTasks ( ) . Count ( x => x . IsCompleted ) ;
94+
95+ await Assert . That ( completedTasks ) . IsEqualTo ( itemCount ) ;
96+
97+ Console . WriteLine ( $ "Total execution time with Thread.Sleep: { stopwatch . Elapsed } ") ;
98+ Console . WriteLine ( $ "Total execution time (seconds): { stopwatch . Elapsed . TotalSeconds : F2} ") ;
99+ Console . WriteLine ( $ "Total execution time (milliseconds): { stopwatch . Elapsed . TotalMilliseconds : F0} ") ;
100+
101+ var expectedSequentialTimeMs = itemCount * sleepMilliseconds ;
102+ Console . WriteLine ( $ "Expected sequential time: { expectedSequentialTimeMs : N0} milliseconds ({ expectedSequentialTimeMs / 1000.0 : F1} seconds)") ;
103+ Console . WriteLine ( $ "Speedup factor: { expectedSequentialTimeMs / stopwatch . Elapsed . TotalMilliseconds : F2} x") ;
104+
105+ await Assert . That ( stopwatch . Elapsed . TotalSeconds ) . IsLessThan ( 10 ) ;
106+ }
107+
108+ [ Test ]
109+ public async Task MeasureParallelProcessingTime_200ItemsWithDirectThreadSleep ( )
110+ {
111+ const int itemCount = 200 ;
112+ const int sleepMilliseconds = 100 ;
113+
114+ var stopwatch = Stopwatch . StartNew ( ) ;
115+
116+ var processor = AsyncProcessorBuilder
117+ . WithItems ( Enumerable . Range ( 0 , itemCount ) )
118+ . ForEachAsync ( _ =>
119+ {
120+ Thread . Sleep ( sleepMilliseconds ) ;
121+ return Task . CompletedTask ;
122+ } )
123+ . ProcessInParallel ( ) ;
124+
125+ await processor ;
126+
127+ stopwatch . Stop ( ) ;
128+
129+ var completedTasks = processor . GetEnumerableTasks ( ) . Count ( x => x . IsCompleted ) ;
130+
131+ await Assert . That ( completedTasks ) . IsEqualTo ( itemCount ) ;
132+
133+ Console . WriteLine ( $ "Total execution time with direct Thread.Sleep: { stopwatch . Elapsed } ") ;
134+ Console . WriteLine ( $ "Total execution time (seconds): { stopwatch . Elapsed . TotalSeconds : F2} ") ;
135+ Console . WriteLine ( $ "Total execution time (milliseconds): { stopwatch . Elapsed . TotalMilliseconds : F0} ") ;
136+
137+ var expectedSequentialTimeMs = itemCount * sleepMilliseconds ;
138+ Console . WriteLine ( $ "Expected sequential time: { expectedSequentialTimeMs : N0} milliseconds ({ expectedSequentialTimeMs / 1000.0 : F1} seconds)") ;
139+ Console . WriteLine ( $ "Speedup factor: { expectedSequentialTimeMs / stopwatch . Elapsed . TotalMilliseconds : F2} x") ;
140+
141+ await Assert . That ( stopwatch . Elapsed . TotalSeconds ) . IsLessThan ( 5 ) ;
142+ }
143+ }
0 commit comments