随着技术的进步、市场的快速发展和系统复杂性的日益增加,软件工程师倾向于跳过软件效率这个令人不舒服的话题。然而,要想节省资金并确保业务成功,战术性的、由可观测性驱动的性能优化对于所有产品来说都是至关重要的。
通过本书,任何工程师都可以轻松学会如何有效、专业且无压力地提高软件效率。作者巴特洛梅耶·普洛特卡讲解了提高系统速度和降低资源消耗所需的工具和知识。本书将指导你使用Go实现更好的日常工作效率。此外,书中大多数内容与语言无关,以便你将小而有效的习惯带入编程或产品管理周期。
本书将教会你如何:
·阐明并协商效率目标
·优化各个层面的效率
·有效利用CPU和内存等公共资源
·通过Prometheus、Jaeger、Parca等开源项目,使用指标、日志记录、跟踪和(连续)剖析等可观测性信号评估效率
·应用go test、pprof、benchstat和k6等工具创建可靠的微观和宏观基准
·高效地使用Go及其特性,如切片、泛型、goroutines、分配语义、垃圾收集等
巴特洛梅耶·普洛特卡(Bartlomiej Ptotka)是Red Hat的首席软件工程师,拥有可观测性和SRE方面的专业背景。他是CNCF大使、TAG可观测性技术负责人以及Thanos项目的联合创始人。此外,他还是包括Prometheus和bingo在内的开源Go项目的核心维护者。
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
Opt