domains / data-systems / ClickHouse/ClickHouse
optimize algorithmic complexity
Always consider the algorithmic complexity and performance implications of data structure choices, memory allocation patterns, and container operations. This includes pre-allocating containers when sizes are known, choosing appropriate data structures based on usage patterns, and measuring performance impact of changes.
Always consider the algorithmic complexity and performance implications of data structure choices, memory allocation patterns, and container operations. This includes pre-allocating containers when sizes are known, choosing appropriate data structures based on usage patterns, and measuring performance impact of changes.
Key practices:
- Pre-allocate containers: Reserve memory when the final size is predictable to avoid repeated reallocations
- Choose containers wisely: Consider trade-offs between different data structures (e.g.,
std::vectorvsstd::unordered_setvsstd::set) based on access patterns, insertion frequency, and memory constraints - Size buffers defensively: When working with external libraries that require “big enough” buffers, add safety margins (e.g., +20%) to prevent overflows
- Benchmark performance changes: Always measure performance impact when modifying algorithms, especially for hot paths
Example of good practice:
// Pre-allocate when size is known
structure_granule.all_paths.reserve(structure_granule.num_paths);
// Choose appropriate container based on usage
// For frequent lookups with few duplicates: std::unordered_set
// For ordered iteration: std::set
// For simple iteration: std::vector
constexpr size_t initial_size_degree = 9; // Conservative default for hash tables
ClearableHashSetWithStackMemory<ValueType, DefaultHash<ValueType>, initial_size_degree> set;
// Size buffers defensively for external libraries
PaddedPODArray<UInt32> compressed_buffer(uncompressed_size * 1.2); // +20% safety margin
This approach prevents performance regressions, reduces memory fragmentation, and ensures predictable behavior under different load conditions.