Prompt
Minimize performance overhead by avoiding unnecessary memory allocations, expensive data structures, and redundant object creation. Choose appropriate data types and parameter passing methods based on actual requirements rather than convenience.
Key practices:
- Use simpler data types when complex ones aren’t needed (e.g.,
int32_t[]instead ofSmallVector<APInt>for fixed-size arrays) - Pass parameters efficiently (
StringRefinstead ofconst std::string&,std::move()for transferring ownership) - Avoid expensive utility classes when simpler alternatives exist (e.g., replacing
TrackingVHwith visited sets where possible) - Reuse resources instead of creating new ones (e.g., reusing thread arrays in loops rather than creating new ones each iteration)
- Use efficient string building methods (
std::stringstreamorformatv()instead of repeated concatenation) - Prevent memory leaks from dynamic allocations by using RAII or smart pointers
Example of inefficient vs efficient approaches:
// Inefficient: Creates many temporary strings and copies
std::string result = "{ ";
for (size_t i = 0; i < items.size(); ++i) {
result += "\"" + items[i].first + "\", " + items[i].second;
if (i < items.size() - 1) result += ", ";
}
// Efficient: Uses stringstream to avoid copies
std::stringstream ss;
ss << "{ ";
for (size_t i = 0; i < items.size(); ++i) {
ss << "\"" << items[i].first << "\", " << items[i].second;
if (i < items.size() - 1) ss << ", ";
}
std::string result = ss.str();
Profile performance-critical code paths to identify where expensive operations like TrackingVH creation or unnecessary allocations are causing bottlenecks, then replace them with more efficient alternatives.