Improve perf for worker
This commit is contained in:
693
.cursor/commands/optimize-current-code.md
Normal file
693
.cursor/commands/optimize-current-code.md
Normal file
@@ -0,0 +1,693 @@
|
|||||||
|
# optimize-current-code
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use this command when you want to:
|
||||||
|
- Optimize performance of existing C# backend code
|
||||||
|
- Optimize React/TypeScript frontend code
|
||||||
|
- Improve code quality and maintainability
|
||||||
|
- Reduce technical debt
|
||||||
|
- Apply best practices to existing code
|
||||||
|
- Optimize database queries and API calls
|
||||||
|
- Improve bundle size and loading performance (frontend)
|
||||||
|
- Enhance memory usage and efficiency (backend)
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
**For C# Backend:**
|
||||||
|
- .NET SDK installed (`dotnet --version`)
|
||||||
|
- Solution builds successfully
|
||||||
|
- Understanding of current code functionality
|
||||||
|
|
||||||
|
**For React Frontend:**
|
||||||
|
- Node.js and npm installed
|
||||||
|
- Dependencies installed (`npm install`)
|
||||||
|
- Application runs without errors
|
||||||
|
|
||||||
|
## Execution Steps
|
||||||
|
|
||||||
|
### Step 1: Identify Code Type and Scope
|
||||||
|
|
||||||
|
Determine what type of code needs optimization:
|
||||||
|
|
||||||
|
**Ask user to confirm:**
|
||||||
|
- Is this C# backend code or React frontend code?
|
||||||
|
- What specific file(s) or component(s) need optimization?
|
||||||
|
- Are there specific performance issues or goals?
|
||||||
|
|
||||||
|
**If not specified:**
|
||||||
|
- Analyze current file in editor
|
||||||
|
- Determine language/framework from file extension
|
||||||
|
- Proceed with appropriate optimization strategy
|
||||||
|
|
||||||
|
### Step 2: Analyze Current Code
|
||||||
|
|
||||||
|
**For C# Backend (.cs files):**
|
||||||
|
|
||||||
|
Read and analyze the code for:
|
||||||
|
|
||||||
|
1. **LINQ Query Optimization**
|
||||||
|
- N+1 query problems
|
||||||
|
- Inefficient `ToList()` calls
|
||||||
|
- Missing `AsNoTracking()` for read-only queries
|
||||||
|
- Complex queries that could be simplified
|
||||||
|
|
||||||
|
2. **Async/Await Patterns**
|
||||||
|
- Missing `async/await` for I/O operations
|
||||||
|
- Blocking calls that should be async
|
||||||
|
- Unnecessary `async` keywords
|
||||||
|
|
||||||
|
3. **Memory Management**
|
||||||
|
- Large object allocations
|
||||||
|
- String concatenation in loops
|
||||||
|
- Unnecessary object creation
|
||||||
|
- Missing `using` statements for disposables
|
||||||
|
|
||||||
|
4. **Code Structure**
|
||||||
|
- Duplicate code
|
||||||
|
- Long methods (>50 lines)
|
||||||
|
- Complex conditional logic
|
||||||
|
- Missing abstractions
|
||||||
|
- Business logic in controllers
|
||||||
|
|
||||||
|
5. **Database Operations**
|
||||||
|
- Inefficient queries
|
||||||
|
- Missing indexes (suggest)
|
||||||
|
- Unnecessary data loading
|
||||||
|
- Transaction management
|
||||||
|
|
||||||
|
**For React Frontend (.tsx/.ts files):**
|
||||||
|
|
||||||
|
Read and analyze the code for:
|
||||||
|
|
||||||
|
1. **Component Performance**
|
||||||
|
- Unnecessary re-renders
|
||||||
|
- Missing `React.memo()` for pure components
|
||||||
|
- Missing `useMemo()` for expensive calculations
|
||||||
|
- Missing `useCallback()` for callback props
|
||||||
|
- Large components (>300 lines)
|
||||||
|
|
||||||
|
2. **Data Fetching**
|
||||||
|
- Using `useEffect()` instead of TanStack Query
|
||||||
|
- Missing loading states
|
||||||
|
- Missing error boundaries
|
||||||
|
- No data caching strategy
|
||||||
|
- Redundant API calls
|
||||||
|
|
||||||
|
3. **Bundle Size**
|
||||||
|
- Large dependencies
|
||||||
|
- Missing code splitting
|
||||||
|
- Missing lazy loading
|
||||||
|
- Unused imports
|
||||||
|
|
||||||
|
4. **Code Structure**
|
||||||
|
- Duplicate components
|
||||||
|
- Complex component logic
|
||||||
|
- Missing custom hooks
|
||||||
|
- Props drilling
|
||||||
|
- Inline styles/functions
|
||||||
|
|
||||||
|
5. **Type Safety**
|
||||||
|
- Missing TypeScript types
|
||||||
|
- `any` types usage
|
||||||
|
- Missing interface definitions
|
||||||
|
|
||||||
|
### Step 3: Create Optimization Plan
|
||||||
|
|
||||||
|
Based on analysis, create prioritized optimization plan:
|
||||||
|
|
||||||
|
**Priority 1 (Critical - Performance Impact):**
|
||||||
|
- N+1 queries
|
||||||
|
- Memory leaks
|
||||||
|
- Blocking I/O operations
|
||||||
|
- Unnecessary re-renders
|
||||||
|
- Large bundle size issues
|
||||||
|
|
||||||
|
**Priority 2 (High - Code Quality):**
|
||||||
|
- Missing async/await
|
||||||
|
- Duplicate code
|
||||||
|
- Business logic in wrong layers
|
||||||
|
- Missing error handling
|
||||||
|
- Poor type safety
|
||||||
|
|
||||||
|
**Priority 3 (Medium - Maintainability):**
|
||||||
|
- Long methods/components
|
||||||
|
- Complex conditionals
|
||||||
|
- Missing abstractions
|
||||||
|
- Code organization
|
||||||
|
|
||||||
|
**Present plan to user:**
|
||||||
|
- Show identified issues
|
||||||
|
- Explain priority and impact
|
||||||
|
- Ask for confirmation to proceed
|
||||||
|
|
||||||
|
### Step 4: Apply C# Backend Optimizations
|
||||||
|
|
||||||
|
**Optimization 1: Fix N+1 Query Problems**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```csharp
|
||||||
|
var orders = await context.Orders.ToListAsync();
|
||||||
|
foreach (var order in orders)
|
||||||
|
{
|
||||||
|
order.Customer = await context.Customers.FindAsync(order.CustomerId);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```csharp
|
||||||
|
var orders = await context.Orders
|
||||||
|
.Include(o => o.Customer)
|
||||||
|
.ToListAsync();
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 2: Add AsNoTracking for Read-Only Queries**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```csharp
|
||||||
|
public async Task<List<Product>> GetProductsAsync()
|
||||||
|
{
|
||||||
|
return await context.Products.ToListAsync();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```csharp
|
||||||
|
public async Task<List<Product>> GetProductsAsync()
|
||||||
|
{
|
||||||
|
return await context.Products
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 3: Move Business Logic from Controllers**
|
||||||
|
|
||||||
|
**Before (Controller):**
|
||||||
|
```csharp
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> CreateOrder(OrderDto dto)
|
||||||
|
{
|
||||||
|
var order = new Order { /* mapping logic */ };
|
||||||
|
var total = 0m;
|
||||||
|
foreach (var item in dto.Items)
|
||||||
|
{
|
||||||
|
total += item.Price * item.Quantity;
|
||||||
|
}
|
||||||
|
order.Total = total;
|
||||||
|
await context.Orders.AddAsync(order);
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
return Ok(order);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After (Controller):**
|
||||||
|
```csharp
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> CreateOrder(CreateOrderCommand command)
|
||||||
|
{
|
||||||
|
var result = await mediator.Send(command);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After (Service/Handler):**
|
||||||
|
```csharp
|
||||||
|
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, OrderResult>
|
||||||
|
{
|
||||||
|
public async Task<OrderResult> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var order = request.ToEntity();
|
||||||
|
order.CalculateTotal(); // Business logic in domain
|
||||||
|
await repository.AddAsync(order, cancellationToken);
|
||||||
|
return order.ToResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 4: Optimize String Operations**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```csharp
|
||||||
|
string result = "";
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
result += item.Name + ", ";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```csharp
|
||||||
|
var result = string.Join(", ", items.Select(i => i.Name));
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 5: Improve LINQ Efficiency**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```csharp
|
||||||
|
var results = await context.Orders
|
||||||
|
.ToListAsync();
|
||||||
|
results = results.Where(o => o.Total > 100).ToList();
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```csharp
|
||||||
|
var results = await context.Orders
|
||||||
|
.Where(o => o.Total > 100)
|
||||||
|
.ToListAsync();
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 6: Add Caching for Expensive Operations**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```csharp
|
||||||
|
public async Task<List<Category>> GetCategoriesAsync()
|
||||||
|
{
|
||||||
|
return await context.Categories.ToListAsync();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```csharp
|
||||||
|
public async Task<List<Category>> GetCategoriesAsync()
|
||||||
|
{
|
||||||
|
var cacheKey = "all-categories";
|
||||||
|
if (cache.TryGetValue(cacheKey, out List<Category> categories))
|
||||||
|
{
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
categories = await context.Categories
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
cache.Set(cacheKey, categories, TimeSpan.FromMinutes(10));
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Apply React Frontend Optimizations
|
||||||
|
|
||||||
|
**Optimization 1: Replace useEffect with TanStack Query**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```typescript
|
||||||
|
function ProductList() {
|
||||||
|
const [products, setProducts] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch('/api/products')
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
setProducts(data);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (loading) return <div>Loading...</div>;
|
||||||
|
return <div>{products.map(p => <ProductCard key={p.id} {...p} />)}</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```typescript
|
||||||
|
function ProductList() {
|
||||||
|
const { data: products, isLoading } = useQuery({
|
||||||
|
queryKey: ['products'],
|
||||||
|
queryFn: () => productsService.getAll()
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isLoading) return <div>Loading...</div>;
|
||||||
|
return <div>{products?.map(p => <ProductCard key={p.id} {...p} />)}</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 2: Memoize Expensive Calculations**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```typescript
|
||||||
|
function OrderSummary({ items }: { items: OrderItem[] }) {
|
||||||
|
const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
||||||
|
const tax = total * 0.1;
|
||||||
|
const grandTotal = total + tax;
|
||||||
|
|
||||||
|
return <div>Total: ${grandTotal}</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```typescript
|
||||||
|
function OrderSummary({ items }: { items: OrderItem[] }) {
|
||||||
|
const { total, tax, grandTotal } = useMemo(() => {
|
||||||
|
const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
||||||
|
const tax = total * 0.1;
|
||||||
|
return { total, tax, grandTotal: total + tax };
|
||||||
|
}, [items]);
|
||||||
|
|
||||||
|
return <div>Total: ${grandTotal}</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 3: Memoize Components**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```typescript
|
||||||
|
function ProductCard({ name, price, onAdd }: ProductCardProps) {
|
||||||
|
return (
|
||||||
|
<div className="card">
|
||||||
|
<h3>{name}</h3>
|
||||||
|
<p>${price}</p>
|
||||||
|
<button onClick={() => onAdd()}>Add</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```typescript
|
||||||
|
const ProductCard = React.memo(function ProductCard({ name, price, onAdd }: ProductCardProps) {
|
||||||
|
return (
|
||||||
|
<div className="card">
|
||||||
|
<h3>{name}</h3>
|
||||||
|
<p>${price}</p>
|
||||||
|
<button onClick={() => onAdd()}>Add</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 4: Use useCallback for Callbacks**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```typescript
|
||||||
|
function ProductList() {
|
||||||
|
const [cart, setCart] = useState([]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{products.map(p => (
|
||||||
|
<ProductCard
|
||||||
|
key={p.id}
|
||||||
|
{...p}
|
||||||
|
onAdd={() => setCart([...cart, p])}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```typescript
|
||||||
|
function ProductList() {
|
||||||
|
const [cart, setCart] = useState([]);
|
||||||
|
|
||||||
|
const handleAdd = useCallback((product: Product) => {
|
||||||
|
setCart(prev => [...prev, product]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{products.map(p => (
|
||||||
|
<ProductCard
|
||||||
|
key={p.id}
|
||||||
|
{...p}
|
||||||
|
onAdd={() => handleAdd(p)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 5: Extract Custom Hooks**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```typescript
|
||||||
|
function ProductList() {
|
||||||
|
const [products, setProducts] = useState([]);
|
||||||
|
const [filtered, setFiltered] = useState([]);
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const results = products.filter(p =>
|
||||||
|
p.name.toLowerCase().includes(search.toLowerCase())
|
||||||
|
);
|
||||||
|
setFiltered(results);
|
||||||
|
}, [products, search]);
|
||||||
|
|
||||||
|
// render logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```typescript
|
||||||
|
function useProductFilter(products: Product[], search: string) {
|
||||||
|
return useMemo(() =>
|
||||||
|
products.filter(p =>
|
||||||
|
p.name.toLowerCase().includes(search.toLowerCase())
|
||||||
|
),
|
||||||
|
[products, search]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProductList() {
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const { data: products } = useQuery(['products'], getProducts);
|
||||||
|
const filtered = useProductFilter(products ?? [], search);
|
||||||
|
|
||||||
|
// render logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 6: Implement Code Splitting**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```typescript
|
||||||
|
import { HeavyComponent } from './HeavyComponent';
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return <HeavyComponent />;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```typescript
|
||||||
|
import { lazy, Suspense } from 'react';
|
||||||
|
|
||||||
|
const HeavyComponent = lazy(() => import('./HeavyComponent'));
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
|
<HeavyComponent />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimization 7: Fix Type Safety**
|
||||||
|
|
||||||
|
**Before:**
|
||||||
|
```typescript
|
||||||
|
function processData(data: any) {
|
||||||
|
return data.map((item: any) => item.value);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After:**
|
||||||
|
```typescript
|
||||||
|
interface DataItem {
|
||||||
|
id: string;
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function processData(data: DataItem[]): number[] {
|
||||||
|
return data.map(item => item.value);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 6: Verify Optimizations
|
||||||
|
|
||||||
|
**For C# Backend:**
|
||||||
|
|
||||||
|
1. **Build solution:**
|
||||||
|
```bash
|
||||||
|
dotnet build src/Managing.sln
|
||||||
|
```
|
||||||
|
- Ensure no compilation errors
|
||||||
|
- Check for new warnings
|
||||||
|
|
||||||
|
2. **Run tests (if available):**
|
||||||
|
```bash
|
||||||
|
dotnet test src/Managing.sln
|
||||||
|
```
|
||||||
|
- Verify all tests pass
|
||||||
|
- Check for performance improvements
|
||||||
|
|
||||||
|
3. **Review changes:**
|
||||||
|
- Ensure business logic unchanged
|
||||||
|
- Verify API contracts maintained
|
||||||
|
- Check error handling preserved
|
||||||
|
|
||||||
|
**For React Frontend:**
|
||||||
|
|
||||||
|
1. **Check TypeScript:**
|
||||||
|
```bash
|
||||||
|
npm run type-check
|
||||||
|
```
|
||||||
|
- Ensure no type errors
|
||||||
|
|
||||||
|
2. **Run linter:**
|
||||||
|
```bash
|
||||||
|
npm run lint
|
||||||
|
```
|
||||||
|
- Fix any new linting issues
|
||||||
|
|
||||||
|
3. **Test component:**
|
||||||
|
```bash
|
||||||
|
npm run test:single test/path/to/component.test.tsx
|
||||||
|
```
|
||||||
|
- Verify component behavior unchanged
|
||||||
|
|
||||||
|
4. **Check bundle size:**
|
||||||
|
- Look for improvements in bundle size
|
||||||
|
- Verify lazy loading works
|
||||||
|
|
||||||
|
5. **Manual testing:**
|
||||||
|
- Test component functionality
|
||||||
|
- Verify no regressions
|
||||||
|
- Check loading states
|
||||||
|
- Verify error handling
|
||||||
|
|
||||||
|
### Step 7: Document Changes
|
||||||
|
|
||||||
|
Create summary of optimizations:
|
||||||
|
|
||||||
|
**Changes made:**
|
||||||
|
- List each optimization
|
||||||
|
- Show before/after metrics (if available)
|
||||||
|
- Explain impact of changes
|
||||||
|
|
||||||
|
**Performance improvements:**
|
||||||
|
- Query time reductions
|
||||||
|
- Memory usage improvements
|
||||||
|
- Bundle size reductions
|
||||||
|
- Render time improvements
|
||||||
|
|
||||||
|
**Code quality improvements:**
|
||||||
|
- Better type safety
|
||||||
|
- Reduced duplication
|
||||||
|
- Better separation of concerns
|
||||||
|
- Improved maintainability
|
||||||
|
|
||||||
|
## Common Optimization Patterns
|
||||||
|
|
||||||
|
### C# Backend Patterns
|
||||||
|
|
||||||
|
1. **Repository Pattern with Specification**
|
||||||
|
- Encapsulate query logic
|
||||||
|
- Reusable query specifications
|
||||||
|
- Better testability
|
||||||
|
|
||||||
|
2. **CQRS with MediatR**
|
||||||
|
- Separate read/write operations
|
||||||
|
- Better performance tuning
|
||||||
|
- Cleaner code organization
|
||||||
|
|
||||||
|
3. **Caching Strategy**
|
||||||
|
- In-memory cache for frequent reads
|
||||||
|
- Distributed cache for scalability
|
||||||
|
- Cache invalidation patterns
|
||||||
|
|
||||||
|
4. **Async Best Practices**
|
||||||
|
- Use `async/await` consistently
|
||||||
|
- Avoid `Task.Result` or `.Wait()`
|
||||||
|
- Use `ConfigureAwait(false)` in libraries
|
||||||
|
|
||||||
|
### React Frontend Patterns
|
||||||
|
|
||||||
|
1. **Data Fetching Pattern**
|
||||||
|
- Always use TanStack Query
|
||||||
|
- Implement proper error boundaries
|
||||||
|
- Use suspense for loading states
|
||||||
|
|
||||||
|
2. **Component Composition**
|
||||||
|
- Split large components
|
||||||
|
- Create reusable atoms/molecules
|
||||||
|
- Use compound component pattern
|
||||||
|
|
||||||
|
3. **State Management**
|
||||||
|
- Keep state as local as possible
|
||||||
|
- Use context sparingly
|
||||||
|
- Consider Zustand for global state
|
||||||
|
|
||||||
|
4. **Performance Pattern**
|
||||||
|
- Memoize expensive operations
|
||||||
|
- Use React.memo for pure components
|
||||||
|
- Implement virtualization for long lists
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
**If build fails after C# optimization:**
|
||||||
|
- Review changes carefully
|
||||||
|
- Check for type mismatches
|
||||||
|
- Verify async/await patterns correct
|
||||||
|
- Rollback if necessary
|
||||||
|
|
||||||
|
**If types break after frontend optimization:**
|
||||||
|
- Check interface definitions
|
||||||
|
- Verify generic types
|
||||||
|
- Update type imports
|
||||||
|
|
||||||
|
**If tests fail after optimization:**
|
||||||
|
- Review test expectations
|
||||||
|
- Update mocks if needed
|
||||||
|
- Verify behavior unchanged
|
||||||
|
|
||||||
|
**If performance degrades:**
|
||||||
|
- Review optimization approach
|
||||||
|
- Check for introduced inefficiencies
|
||||||
|
- Consider alternative approach
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- ✅ **Always test after optimization** - Verify functionality unchanged
|
||||||
|
- ✅ **Measure performance** - Use profiling tools to verify improvements
|
||||||
|
- ✅ **Keep it simple** - Don't over-optimize premature code
|
||||||
|
- ✅ **Follow patterns** - Use established patterns from codebase
|
||||||
|
- ⚠️ **Avoid premature optimization** - Focus on actual bottlenecks
|
||||||
|
- ⚠️ **Maintain readability** - Don't sacrifice clarity for minor gains
|
||||||
|
- 📊 **Profile first** - Identify real performance issues before optimizing
|
||||||
|
- 🧪 **Test thoroughly** - Ensure no regressions introduced
|
||||||
|
- 📝 **Document changes** - Explain why optimizations were made
|
||||||
|
|
||||||
|
## Example Execution
|
||||||
|
|
||||||
|
**User input:** `/optimize-current-code`
|
||||||
|
|
||||||
|
**AI execution:**
|
||||||
|
|
||||||
|
1. Identify code type: React component (ProductList.tsx)
|
||||||
|
2. Analyze code: Found useEffect for data fetching, no memoization
|
||||||
|
3. Present plan:
|
||||||
|
- Replace useEffect with TanStack Query
|
||||||
|
- Add React.memo to child components
|
||||||
|
- Extract custom hooks
|
||||||
|
4. Apply optimizations (show diffs)
|
||||||
|
5. Verify: Run type-check and tests
|
||||||
|
6. Summary: "✅ Optimized ProductList component - replaced useEffect with TanStack Query, memoized child components"
|
||||||
|
|
||||||
|
**For C# backend:**
|
||||||
|
|
||||||
|
1. Identify code type: Service class with database operations
|
||||||
|
2. Analyze code: Found N+1 query, missing AsNoTracking, business logic
|
||||||
|
3. Present plan:
|
||||||
|
- Fix N+1 with Include
|
||||||
|
- Add AsNoTracking for read-only
|
||||||
|
- Move business logic to domain
|
||||||
|
4. Apply optimizations
|
||||||
|
5. Verify: Build and test
|
||||||
|
6. Summary: "✅ Optimized OrderService - eliminated N+1 queries, added AsNoTracking, moved business logic to domain layer"
|
||||||
|
|
||||||
@@ -227,6 +227,7 @@ public class BacktestExecutor
|
|||||||
// Use optimized rolling window approach - TradingBox.GetSignal only needs last 600 candles
|
// Use optimized rolling window approach - TradingBox.GetSignal only needs last 600 candles
|
||||||
const int rollingWindowSize = 600;
|
const int rollingWindowSize = 600;
|
||||||
var rollingCandles = new List<Candle>(rollingWindowSize); // Pre-allocate capacity for better performance
|
var rollingCandles = new List<Candle>(rollingWindowSize); // Pre-allocate capacity for better performance
|
||||||
|
var fixedCandlesHashSet = new HashSet<Candle>(rollingWindowSize); // Reuse HashSet to avoid allocations
|
||||||
var candlesProcessed = 0;
|
var candlesProcessed = 0;
|
||||||
|
|
||||||
// Signal caching optimization - reduce signal update frequency for better performance
|
// Signal caching optimization - reduce signal update frequency for better performance
|
||||||
@@ -259,10 +260,14 @@ public class BacktestExecutor
|
|||||||
|
|
||||||
if (rollingCandles.Count > rollingWindowSize)
|
if (rollingCandles.Count > rollingWindowSize)
|
||||||
{
|
{
|
||||||
// Remove oldest candle (first element) - O(n) but acceptable for small window
|
// Remove oldest candle from both structures
|
||||||
|
var removedCandle = rollingCandles[0];
|
||||||
rollingCandles.RemoveAt(0);
|
rollingCandles.RemoveAt(0);
|
||||||
|
fixedCandlesHashSet.Remove(removedCandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to HashSet for reuse
|
||||||
|
fixedCandlesHashSet.Add(candle);
|
||||||
tradingBot.LastCandle = candle;
|
tradingBot.LastCandle = candle;
|
||||||
|
|
||||||
// Smart signal caching - reduce signal update frequency for performance
|
// Smart signal caching - reduce signal update frequency for performance
|
||||||
@@ -276,10 +281,9 @@ public class BacktestExecutor
|
|||||||
|
|
||||||
if (!shouldSkipSignalUpdate)
|
if (!shouldSkipSignalUpdate)
|
||||||
{
|
{
|
||||||
// Convert to HashSet only when needed for GetSignal (it expects HashSet)
|
// Reuse the pre-allocated HashSet instead of creating new one
|
||||||
var fixedCandles = new HashSet<Candle>(rollingCandles);
|
|
||||||
var signalUpdateStart = Stopwatch.GetTimestamp();
|
var signalUpdateStart = Stopwatch.GetTimestamp();
|
||||||
await tradingBot.UpdateSignals(fixedCandles);
|
await tradingBot.UpdateSignals(fixedCandlesHashSet);
|
||||||
signalUpdateTotalTime += Stopwatch.GetElapsedTime(signalUpdateStart);
|
signalUpdateTotalTime += Stopwatch.GetElapsedTime(signalUpdateStart);
|
||||||
telemetry.TotalSignalUpdates++;
|
telemetry.TotalSignalUpdates++;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user