內容大鋼
隨著技術的進步、市場的快速發展和系統複雜性的日益增加,軟體工程師傾向於跳過軟體效率這個令人不舒服的話題。然而,要想節省資金並確保業務成功,戰術性的、由可觀測性驅動的性能優化對於所有產品來說都是至關重要的。
通過本書,任何工程師都可以輕鬆學會如何有效、專業且無壓力地提高軟體效率。作者巴特洛梅耶·普洛特卡講解了提高系統速度和降低資源消耗所需的工具和知識。本書將指導你使用Go實現更好的日常工作效率。此外,書中大多數內容與語言無關,以便你將小而有效的習慣帶入編程或產品管理周期。
本書將教會你如何:
·闡明並協商效率目標
·優化各個層面的效率
·有效利用CPU和內存等公共資源
·通過Prometheus、Jaeger、Parca等開源項目,使用指標、日誌記錄、跟蹤和(連續)剖析等可觀測性信號評估效率
·應用go test、pprof、benchstat和k6等工具創建可靠的微觀和宏觀基準
·高效地使用Go及其特性,如切片、泛型、goroutines、分配語義、垃圾收集等
目錄
Preface
1. Software Efficiency Matters
Behind Performance
Common Efficiency Misconceptions
Optimized Code Is Not Readable
You Aren't Going to Need It
Hardware Is Getting Faster and Cheaper
We Can Scale Horizontally Instead
Time to Market Is More Important
The Key to Pragmatic Code Performance
Summary
2. Efficient Introduction to Go
Basics You Should Know About Go
Imperative, Compiled, and Statically Typed Language
Designed to Improve Serious Codebases
Governed by Google, Yet Open Source
Simplicity, Safety, and Readability Are Paramount
Packaging and Modules
Dependencies Transparency by Default
Consistent Tooling
Single Way of Handling Errors
Strong Ecosystem
Unused Import or Variable Causes Build Error
Unit Testing and Table Tests
Advanced Language Elements
Code Documentation as a First Citizen
Backward Compatibility and Portability
Go Runtime
Object-Oriented Programming
Generics
Is Go "Fast"?
Summary
3. Conquering Efficiency
Beyond Waste, Optimization Is a Zero-Sum Game
Reasonable Optimizations
Deliberate Optimizations
Optimization Challenges
Understand Your Goals
Efficiency Requirements Should Be Formalized
Resource-Aware Efficiency Requirements
Acquiring and Assessing Efficiency Goals
Example of Defining RAER
Got an Efficiency Problem? Keep Calm!
Optimization Design Levels
Efficiency-Aware Development Flow
Functionality Phase
Efficiency Phase
Summary
4. How Go Uses the CPU Resource (or Two)
CPU in a Modern Computer Architecture
Assembly
Understanding Go Compiler
CPU and Memory Wall Problem
Hierachical Cache System
Pipelining and Out-of-Order Execution
Hyper-Threading
Schedulers
Operating System Scheduler
Go Runtime Scheduler
When to Use Concurrency
Summary
5. How Go Uses Memory Resource
Memory Relevance
Do We Have a Memory Problem?
Physical Memory
OS Memory Management
Virtual Memory
mmap Syscall
OS Memory Mapping
Go Memory Management
Values, Pointers, and Memory Blocks
Go Allocator
Garbage Collection
Summary
6. Efficiency Observability
Observability
Example: Instrumenting for Latency
Logging
Tracing
Metrics
Efficiency Metrics Semantics
Latency
CPU Usage
Memory Usage
Summary
7. Data-Driven Efficiency Assessment
Complexity Analysis
"Estimated" Efficiency Complexity
Asymptotic Complexity with Big 0 Notation
Practical Applications
The Art of Benchmarking
Comparison to Functional Testing
Benchmarks Lie
Reliability of Experiments
Human Errors
Reproducing Production
Performance Nondeterminism
Benchmarking Levels
Benchmarking in Production
Macrobenchmarks
Microbenchmarks
What Level Should You Use?
Summary
8. Benchmarking
Microbenchmarks
Go Benchmarks
Understanding the Results
Tips and Tricks for Microbenchmarking
Too-High Variance
Find Your Workflow
Test Your Benchmark for Correctness!
Sharing Benchmarks with the Team (and Your Future Self)
Running Benchmarks for Different Inputs
Microbenchmarks Versus Memory Management
Compiler Optimizations Versus Benchmark
Macrobenchmarks
Basics
Go e2e Framework
Understanding Results and Observations
Common Macrobenchmarking Workflows
Summary
9. Data-Driven Bottleneck Analysis
Root Cause Analysis, but for Efficiency
Profiling in Go
pprof Format
go tool pprof Reports
Capturing the Profiling Signal
Common Profile Instrumentation
Heap
Goroutine
CPU
Off-CPU Time
Tips and Tricks
Sharing Profiles
Continuous Profiling
Comparing and Aggregating Profiles
Summary
10. Optimization Examples
Sum Examples
Optimizing Latency
Optimizing bytes.Split
Optimizing runtime.slicebytetostring
Optimizing strconv.Parse
Optimizing Memory Usage
Moving to Streaming Algorithm
Optimizing bufio.Scanner
Optimizing Latency Using Concurrency
A Naive Concurrency
A Worker Approach with Distribution
A Worker Approach Without Coordination (Sharding)
A Streamed, Sharded Worker Approach
Bonus: Thinking Out of the Box
Summary
11. Optimization Patterns
Common Patterns
Do Less Work
Trading Functionality for Efficiency
Trading Space for Time
Trading Time for Space
The Three Rs Optimization Method
Reduce Allocations
Reuse Memory
Recycle
Don't Leak Resources
Control the Lifecycle of Your Goroutines
Reliably Close Things
Exhaust Things
Pre-Allocate If You Can
Overusing Memory with Arrays
Memory Reuse and Pooling
Summary
Next Steps
A. Latencies for Napkin Math Calculations
Index