Deno 的性能优化对于构建高性能应用程序至关重要。了解 Deno 的性能特性和优化技巧可以帮助开发者充分发挥其潜力。
性能特性概述
Deno 基于 Rust 和 V8 引擎构建,具有良好的性能基础。通过合理的优化策略,可以进一步提升应用程序的性能。
启动性能优化
1. 减少依赖加载
typescript// 不好的做法:在顶层加载所有依赖 import { heavyModule1 } from "./heavy-module-1.ts"; import { heavyModule2 } from "./heavy-module-2.ts"; import { heavyModule3 } from "./heavy-module-3.ts"; // 好的做法:按需加载 async function processWithHeavyModule1() { const { heavyModule1 } = await import("./heavy-module-1.ts"); return heavyModule1.process(); }
2. 使用缓存
typescript// 缓存编译结果 const cache = new Map<string, any>(); async function getCachedData(key: string, fetcher: () => Promise<any>) { if (cache.has(key)) { return cache.get(key); } const data = await fetcher(); cache.set(key, data); return data; }
3. 预热缓存
typescript// 应用启动时预热缓存 async function warmupCache() { await Promise.all([ getCachedData("config", loadConfig), getCachedData("translations", loadTranslations), ]); } warmupCache().then(() => { console.log("Cache warmed up, ready to serve"); });
运行时性能优化
1. 使用高效的数据结构
typescript// 使用 Map 而不是 Object 进行频繁查找 const userMap = new Map<string, User>(); // 快速查找 function getUser(id: string): User | undefined { return userMap.get(id); } // 使用 Set 进行快速存在性检查 const activeUsers = new Set<string>(); function isActiveUser(id: string): boolean { return activeUsers.has(id); }
2. 避免不必要的计算
typescript// 使用记忆化(Memoization) function memoize<T extends (...args: any[]) => any>(fn: T): T { const cache = new Map<string, ReturnType<T>>(); return ((...args: Parameters<T>) => { const key = JSON.stringify(args); if (cache.has(key)) { return cache.get(key); } const result = fn(...args); cache.set(key, result); return result; }) as T; } // 使用记忆化的函数 const expensiveCalculation = memoize((n: number): number => { console.log(`Calculating for ${n}`); let result = 0; for (let i = 0; i < n * 1000000; i++) { result += i; } return result; }); // 第一次调用会计算 console.log(expensiveCalculation(100)); // 第二次调用使用缓存 console.log(expensiveCalculation(100));
3. 批量处理
typescript// 批量数据库操作 async function batchInsert(items: Item[]): Promise<void> { const batchSize = 100; for (let i = 0; i < items.length; i += batchSize) { const batch = items.slice(i, i + batchSize); await insertBatch(batch); } } // 批量 API 请求 async function batchFetch(urls: string[]): Promise<Response[]> { const batchSize = 10; const results: Response[] = []; for (let i = 0; i < urls.length; i += batchSize) { const batch = urls.slice(i, i + batchSize); const batchResults = await Promise.all( batch.map(url => fetch(url)) ); results.push(...batchResults); } return results; }
内存优化
1. 避免内存泄漏
typescript// 及时清理资源 class ResourceManager { private resources: Set<Disposable> = new Set(); register(resource: Disposable) { this.resources.add(resource); } cleanup() { for (const resource of this.resources) { resource.dispose(); } this.resources.clear(); } } // 使用 WeakMap 避免强引用 const weakCache = new WeakMap<object, any>(); function cacheData(obj: object, data: any) { weakCache.set(obj, data); }
2. 流式处理大文件
typescript// 使用流处理大文件,避免一次性加载到内存 import { readableStreamFromIterable } from "https://deno.land/std@0.208.0/streams/mod.ts"; async function processLargeFile(filePath: string) { const file = await Deno.open(filePath); const reader = file.readable.getReader(); const buffer = new Uint8Array(1024 * 1024); // 1MB buffer while (true) { const { done, value } = await reader.read(buffer); if (done) break; // 处理数据块 processDataChunk(value); } file.close(); }
3. 对象池模式
typescript// 对象池重用对象,减少 GC 压力 class ObjectPool<T> { private pool: T[] = []; private factory: () => T; private reset: (obj: T) => void; constructor( factory: () => T, reset: (obj: T) => void, initialSize: number = 10 ) { this.factory = factory; this.reset = reset; for (let i = 0; i < initialSize; i++) { this.pool.push(factory()); } } acquire(): T { return this.pool.pop() || this.factory(); } release(obj: T) { this.reset(obj); this.pool.push(obj); } } // 使用对象池 const bufferPool = new ObjectPool( () => new Uint8Array(1024 * 1024), (buffer) => buffer.fill(0), 5 ); async function processData() { const buffer = bufferPool.acquire(); try { // 使用 buffer 处理数据 await processWithBuffer(buffer); } finally { bufferPool.release(buffer); } }
并发性能优化
1. 使用 Worker 并行处理
typescript// 使用 Worker 进行 CPU 密集型任务 import { WorkerPool } from "./worker-pool.ts"; const pool = new WorkerPool("./data-processor.ts", 4); async function parallelProcess(data: any[]) { const promises = data.map(item => pool.execute(item)); return Promise.all(promises); }
2. 控制并发数量
typescript// 控制并发请求数量 class ConcurrencyController { private running: Set<Promise<any>> = new Set(); private maxConcurrent: number; constructor(maxConcurrent: number) { this.maxConcurrent = maxConcurrent; } async execute<T>(task: () => Promise<T>): Promise<T> { while (this.running.size >= this.maxConcurrent) { await Promise.race(this.running); } const promise = task().finally(() => { this.running.delete(promise); }); this.running.add(promise); return promise; } } const controller = new ConcurrencyController(10); async function fetchWithConcurrency(urls: string[]) { return Promise.all( urls.map(url => controller.execute(() => fetch(url))) ); }
3. 使用异步迭代器
typescript// 使用异步迭代器处理流式数据 async function* processStream(stream: ReadableStream<Uint8Array>) { const reader = stream.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; yield processChunk(value); } } // 使用异步迭代器 for await (const result of processStream(dataStream)) { console.log(result); }
I/O 性能优化
1. 使用异步 I/O
typescript// 始终使用异步 I/O 操作 async function readConfig(): Promise<Config> { const content = await Deno.readTextFile("config.json"); return JSON.parse(content); } // 批量文件操作 async function batchReadFiles(filePaths: string[]): Promise<Map<string, string>> { const results = new Map<string, string>(); await Promise.all( filePaths.map(async (path) => { const content = await Deno.readTextFile(path); results.set(path, content); }) ); return results; }
2. 使用缓存策略
typescript// LRU 缓存实现 class LRUCache<K, V> { private cache: Map<K, V>; private maxSize: number; constructor(maxSize: number) { this.cache = new Map(); this.maxSize = maxSize; } get(key: K): V | undefined { const value = this.cache.get(key); if (value !== undefined) { // 重新插入以更新访问顺序 this.cache.delete(key); this.cache.set(key, value); } return value; } set(key: K, value: V): void { if (this.cache.has(key)) { this.cache.delete(key); } else if (this.cache.size >= this.maxSize) { // 删除最旧的项 const firstKey = this.cache.keys().next().value; this.cache.delete(firstKey); } this.cache.set(key, value); } } // 使用 LRU 缓存 const configCache = new LRUCache<string, Config>(100); async function getConfigWithCache(key: string): Promise<Config> { const cached = configCache.get(key); if (cached) { return cached; } const config = await loadConfig(key); configCache.set(key, config); return config; }
3. HTTP 性能优化
typescript// 使用连接池 import { serve } from "https://deno.land/std@0.208.0/http/server.ts"; const handler = async (req: Request): Promise<Response> => { // 启用压缩 const acceptEncoding = req.headers.get("accept-encoding"); let body = await getResponseBody(); if (acceptEncoding?.includes("gzip")) { body = await compressGzip(body); return new Response(body, { headers: { "Content-Encoding": "gzip", "Content-Type": "application/json", }, }); } return new Response(body, { headers: { "Content-Type": "application/json" }, }); }; // 使用 HTTP/2 await serve(handler, { port: 8000, alpnProtocols: ["h2"], });
监控和调试
1. 性能监控
typescript// 性能监控工具 class PerformanceMonitor { private metrics: Map<string, number[]> = new Map(); record(operation: string, duration: number) { if (!this.metrics.has(operation)) { this.metrics.set(operation, []); } this.metrics.get(operation)!.push(duration); } getStats(operation: string) { const durations = this.metrics.get(operation); if (!durations || durations.length === 0) { return null; } const sorted = [...durations].sort((a, b) => a - b); return { count: durations.length, min: sorted[0], max: sorted[sorted.length - 1], avg: durations.reduce((a, b) => a + b, 0) / durations.length, p50: sorted[Math.floor(sorted.length * 0.5)], p95: sorted[Math.floor(sorted.length * 0.95)], p99: sorted[Math.floor(sorted.length * 0.99)], }; } } // 使用性能监控 const monitor = new PerformanceMonitor(); async function measurePerformance<T>( operation: string, fn: () => Promise<T> ): Promise<T> { const start = performance.now(); try { return await fn(); } finally { const duration = performance.now() - start; monitor.record(operation, duration); } } // 使用示例 await measurePerformance("database-query", async () => { return await db.query("SELECT * FROM users"); });
2. 内存分析
typescript// 内存使用监控 function getMemoryUsage() { return { rss: Deno.memoryUsage().rss / 1024 / 1024, // MB heapTotal: Deno.memoryUsage().heapTotal / 1024 / 1024, heapUsed: Deno.memoryUsage().heapUsed / 1024 / 1024, external: Deno.memoryUsage().external / 1024 / 1024, }; } // 定期报告内存使用 setInterval(() => { const usage = getMemoryUsage(); console.log("Memory usage:", usage); }, 60000); // 每分钟
最佳实践
- 测量优先:在优化前先测量性能瓶颈
- 渐进优化:一次优化一个方面,避免过度优化
- 使用缓存:合理使用缓存减少重复计算
- 异步优先:始终使用异步 I/O 操作
- 批量处理:批量操作减少开销
- 资源管理:及时释放不再使用的资源
- 监控持续:持续监控性能指标
Deno 提供了良好的性能基础,通过合理的优化策略,可以构建高性能的应用程序。记住,过早优化是万恶之源,始终基于实际测量进行优化。