Skip to content

Commit 7fc7bde

Browse files
committed
Updating Zip with sample app source files
1 parent d78ae3a commit 7fc7bde

File tree

5 files changed

+109
-8
lines changed

5 files changed

+109
-8
lines changed
Binary file not shown.

DownloadableCodeProjects/standalone-lab-projects/implement-performance-profiling/ContosoOnlineStore/ContosoOnlineStore.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
<TargetFramework>net9.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
8+
9+
<!-- Enable optimizations even for Debug so that running the app with the
10+
'benchmark' argument via 'dotnet run' produces valid BenchmarkDotNet results.
11+
Without this, a Debug build shows a warning that the assembly is non-optimized. -->
12+
<Optimize>true</Optimize>
13+
814
</PropertyGroup>
915

1016
<ItemGroup>

DownloadableCodeProjects/standalone-lab-projects/implement-performance-profiling/ContosoOnlineStore/PERFORMANCE_GUIDE.md

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This document outlines the intentional performance bottlenecks in the Contoso On
99
### 🔴 Critical Performance Issues
1010

1111
#### 1. Product Catalog Linear Search
12+
1213
**File**: `ProductCatalog.cs`
1314
**Method**: `GetProductById()`
1415
**Issue**: Uses linear search (FirstOrDefault) instead of dictionary lookup
@@ -23,65 +24,79 @@ return _productIndex.TryGetValue(productId, out var product) ? product : null;
2324
```
2425

2526
#### 2. Inefficient Search Implementation
27+
2628
**File**: `ProductCatalog.cs`
2729
**Method**: `SearchProducts()`
28-
**Issues**:
30+
**Issues**:
31+
2932
- Multiple string operations per product
3033
- Inefficient cache key generation
3134
- Sequential processing with artificial delays
3235

3336
**Impact**: High latency for search operations
3437

3538
#### 3. Sequential Order Processing
39+
3640
**File**: `OrderProcessor.cs`
3741
**Method**: `FinalizeOrderAsync()`
3842
**Issues**:
43+
3944
- Individual product lookups in loops
4045
- Sequential inventory checks
4146
- Synchronous receipt generation
4247

4348
### 🟡 Moderate Performance Issues
4449

4550
#### 4. Inventory Management Bottlenecks
51+
4652
**File**: `InventoryManager.cs`
4753
**Method**: `GetLowStockProducts()`
4854
**Issues**:
55+
4956
- Individual database queries simulation
5057
- Inefficient logging implementation
5158
- No batch operations
5259

5360
#### 5. Email Service Delays
61+
5462
**File**: `EmailService.cs`
5563
**Method**: `SendConfirmationAsync()`
5664
**Issues**:
65+
5766
- Sequential email content generation
5867
- Individual product lookups in email templates
5968
- Synchronous validation operations
6069

6170
### 🟢 Minor Performance Issues
6271

6372
#### 6. Excessive Logging Overhead
73+
6474
**Throughout the application**
6575
**Issues**:
76+
6677
- Detailed logging in hot paths
6778
- String concatenation in logging
6879
- Synchronous logging operations
6980

7081
#### 7. Memory Allocation Patterns
82+
7183
**Various files**
7284
**Issues**:
85+
7386
- Frequent list creation and sorting
7487
- String concatenation without StringBuilder
7588
- Cache dictionary overhead
7689

7790
## Performance Optimization Exercise Guide
7891

7992
### Exercise 1: Optimize Product Lookup (Beginner)
93+
8094
**Goal**: Improve product lookup performance from O(n) to O(1)
8195
**Files**: `ProductCatalog.cs`
8296
**Expected Improvement**: 90%+ reduction in lookup time
8397

8498
**Steps**:
99+
85100
1. Identify the linear search in `GetProductById()`
86101
2. Implement dictionary-based product index
87102
3. Update index when products are added/modified
@@ -90,11 +105,13 @@ return _productIndex.TryGetValue(productId, out var product) ? product : null;
90105
**Success Criteria**: Product lookups complete in <1ms
91106

92107
### Exercise 2: Batch Inventory Operations (Intermediate)
108+
93109
**Goal**: Reduce individual database calls
94110
**Files**: `InventoryManager.cs`, `OrderProcessor.cs`
95111
**Expected Improvement**: 70%+ reduction in inventory check time
96112

97113
**Steps**:
114+
98115
1. Identify individual inventory checks in loops
99116
2. Implement batch inventory validation
100117
3. Create bulk stock update operations
@@ -103,11 +120,13 @@ return _productIndex.TryGetValue(productId, out var product) ? product : null;
103120
**Success Criteria**: Batch operations 5x faster than individual calls
104121

105122
### Exercise 3: Async Processing Pipeline (Advanced)
123+
106124
**Goal**: Implement parallel processing for order operations
107125
**Files**: `OrderProcessor.cs`, `EmailService.cs`
108126
**Expected Improvement**: 60%+ reduction in total processing time
109127

110128
**Steps**:
129+
111130
1. Identify sequential operations that can be parallelized
112131
2. Implement async/await patterns properly
113132
3. Create parallel processing for order validation
@@ -116,11 +135,13 @@ return _productIndex.TryGetValue(productId, out var product) ? product : null;
116135
**Success Criteria**: Order processing completes in <500ms
117136

118137
### Exercise 4: Intelligent Caching (Advanced)
138+
119139
**Goal**: Implement comprehensive caching strategy
120140
**Files**: `ProductCatalog.cs`, `OrderProcessor.cs`
121141
**Expected Improvement**: 80%+ improvement in repeated operations
122142

123143
**Steps**:
144+
124145
1. Implement product search result caching
125146
2. Add price calculation caching
126147
3. Create smart cache invalidation
@@ -133,19 +154,65 @@ return _productIndex.TryGetValue(productId, out var product) ? product : null;
133154
### Using Built-in Performance Tracking
134155

135156
The application includes performance counters that display:
157+
136158
- Order processing times
137159
- Individual operation durations
138160
- Memory allocation patterns
139161
- Cache hit/miss ratios
140162

141163
### Running Benchmarks
142164

143-
Use BenchmarkDotNet for detailed analysis:
165+
To use BenchmarkDotNet for detailed analysis, run the following command:
166+
167+
```bash
168+
dotnet run -c Release -- benchmark
169+
```
170+
171+
This command will run the application in Release mode and execute the benchmarks defined in your project.
172+
173+
If you omit the `-c Release` option, the compiler defaults to Debug mode. Since the default value for `Optimize` in a Debug build is `false`, BenchmarkDotNet will detect a non‑optimized assembly. The result is a warning or error “Assembly ... is non-optimized... build it in RELEASE.”
174+
175+
You can update the .csproj file to enable optimizations even for Debug mode so that running the app with the 'benchmark' argument via 'dotnet run' should produce valid BenchmarkDotNet results.
176+
177+
Add the following line inside the main `<PropertyGroup>` in the .csproj file.
178+
179+
```xml
180+
<Optimize>true</Optimize>
181+
```
182+
183+
Without this, a Debug build shows the warning/error that the assembly is non-optimized.
184+
185+
It's best to explicitly use Release (recommended for keeping Debug truly debuggable):
186+
187+
```bash
188+
dotnet run -c Release -- benchmark
189+
```
190+
191+
Warning: Always optimizing Debug can make stepping through code less intuitive. If you
192+
prefer traditional debugging, revert the global <Optimize>true> and instead:
193+
194+
Run benchmarks with -c Release:
195+
196+
```bash
197+
dotnet run -c Release -- benchmark
198+
```
199+
200+
Or add a dedicated configuration:
201+
202+
```xml
203+
<PropertyGroup Condition=\"'$(Configuration)'=='Benchmarks'\">
204+
<Optimize>true</Optimize>
205+
</PropertyGroup>
206+
```
207+
208+
And then run:
209+
144210
```bash
145-
dotnet run -- benchmark
211+
dotnet run -c Benchmarks -- benchmark
146212
```
147213

148-
This provides:
214+
Using BenchmarkDotNet provides:
215+
149216
- Precise timing measurements
150217
- Memory allocation tracking
151218
- Statistical analysis
@@ -154,12 +221,14 @@ This provides:
154221
### Performance Targets
155222

156223
#### Before Optimization (Baseline)
224+
157225
- Order processing: 2000-3000ms
158226
- Product lookup: 10-50ms per operation
159227
- Search operations: 100-500ms
160228
- Inventory checks: 50-200ms
161229

162230
#### After Optimization (Target)
231+
163232
- Order processing: <500ms
164233
- Product lookup: <1ms per operation
165234
- Search operations: <50ms
@@ -168,36 +237,46 @@ This provides:
168237
## Common Optimization Patterns
169238

170239
### 1. Dictionary Lookups
240+
171241
Replace linear searches with dictionary/hash table lookups:
242+
172243
```csharp
173244
// Instead of: list.FirstOrDefault(x => x.Id == id)
174245
// Use: dictionary.TryGetValue(id, out var item)
175246
```
176247

177248
### 2. Batch Operations
249+
178250
Group multiple database operations:
251+
179252
```csharp
180253
// Instead of: multiple individual queries
181254
// Use: single batch query with multiple IDs
182255
```
183256

184257
### 3. Async/Await Best Practices
258+
185259
Properly implement asynchronous operations:
260+
186261
```csharp
187262
// Instead of: Task.Wait() or .Result
188263
// Use: await Task.WhenAll(tasks)
189264
```
190265

191266
### 4. Caching Strategies
267+
192268
Implement multi-level caching:
269+
193270
```csharp
194271
// Memory cache for frequently accessed data
195272
// Distributed cache for shared data
196273
// Smart cache invalidation
197274
```
198275

199276
### 5. Object Pooling
277+
200278
Reuse expensive objects:
279+
201280
```csharp
202281
// Pool StringBuilder, HttpClient, etc.
203282
// Reduce garbage collection pressure
@@ -206,19 +285,23 @@ Reuse expensive objects:
206285
## Profiling Tools Integration
207286

208287
### Visual Studio Diagnostic Tools
288+
209289
- CPU Usage analysis
210290
- Memory Usage tracking
211291
- Events timeline
212292
- Performance tips
213293

214294
### dotMemory/dotTrace
295+
215296
- Memory profiling
216297
- Performance profiling
217298
- Timeline analysis
218299
- Comparison reports
219300

220301
### Application Insights (Simulated)
302+
221303
The application logs performance metrics that simulate:
304+
222305
- Request/response times
223306
- Dependency call durations
224307
- Exception tracking
@@ -227,20 +310,26 @@ The application logs performance metrics that simulate:
227310
## Validation and Testing
228311

229312
### Performance Tests
313+
230314
Run the included performance test suite:
315+
231316
```bash
232317
dotnet test --logger trx --collect:"XPlat Code Coverage"
233318
```
234319

235320
### Load Testing Simulation
321+
236322
The application includes concurrent operation testing:
323+
237324
- Multiple simultaneous orders
238325
- Concurrent product lookups
239326
- Search load testing
240327
- Inventory contention handling
241328

242329
### Regression Testing
330+
243331
Ensure optimizations don't break functionality:
332+
244333
- Unit test coverage >80%
245334
- Integration test scenarios
246335
- Performance benchmark baselines
@@ -249,21 +338,27 @@ Ensure optimizations don't break functionality:
249338
## Real-World Considerations
250339

251340
### Production Deployment
341+
252342
Consider these factors when applying optimizations:
343+
253344
- Database connection pooling
254345
- CDN for static content
255346
- Load balancing strategies
256347
- Auto-scaling configurations
257348

258349
### Monitoring and Alerting
350+
259351
Implement production monitoring:
352+
260353
- Performance threshold alerts
261354
- Error rate monitoring
262355
- Resource utilization tracking
263356
- User experience metrics
264357

265358
### Security Impact
359+
266360
Ensure optimizations don't compromise security:
361+
267362
- Input validation performance
268363
- Rate limiting implementation
269364
- Authentication/authorization caching

DownloadableCodeProjects/standalone-lab-projects/implement-performance-profiling/ContosoOnlineStore/Tests/ContosoOnlineStoreTests.cs

Lines changed: 0 additions & 2 deletions
This file was deleted.

Instructions/Labs/LAB_AK_10_implement_performance_profiling.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,10 @@ Use the following steps to download the sample project and open it in Visual Stu
8484
8585
- GHCopilotEx10LabApps\
8686
- ContosoOnlineStore\
87-
- Benchmarks
87+
- Benchmarks\
8888
- Configuration\
8989
- Exceptions\
9090
- Services\
91-
- Tests\
9291
- appsettings.json
9392
- InventoryManager.cs
9493
- Orders.cs
@@ -99,6 +98,9 @@ Use the following steps to download the sample project and open it in Visual Stu
9998
- ProductCatalog.cs
10099
- Program.cs
101100
- README.md
101+
- ContosoOnlineStore.Tests\
102+
- ContosoOnlineStoreTests.cs
103+
- Usings.cs
102104
- DataAnalyzerReporter\
103105
104106
## Exercise scenario

0 commit comments

Comments
 (0)