Parameter Optimization
Prerequisites
1. Why Parameter Passing Matters
Passing parameters incorrectly can introduce hidden costs:
- Temporary object creation
- Unnecessary copies
- Cache inefficiency
Even small overhead becomes significant in tight loops or large-scale systems.
- Does this create a copy?
- Is this object large?
- Can I avoid unnecessary construction?
2. Call by Value vs Call by Reference
❌ Expensive (Copy)
1
2
3
4
| void process(std::string s)
{
// copy occurs
}
|
std::string copy = allocation + memory copy
✔ Efficient (Reference)
1
2
3
4
| void process(const std::string& s)
{
// no copy
}
|
- No temporary object
- No memory allocation
2-1. When Call by Value is OK
✔ Small types (int, float, pointer)
✔ When copy is cheap
✔ When you need a local copy anyway
2-2. Minimizing Copies
✔ Pass only what is needed
1
2
3
4
5
| // ❌ Bad
void process(User user);
// ✔ Better
void process(const User& user);
|
✔ Avoid unnecessary temporaries
1
| process(std::string("hello")); // temporary object created
|
std::string_view Optimization
1
| void process(std::string_view s);
|
3. Copy Elision (C++17)
Compiler can eliminate copies automatically
1
2
| std::string create()
return std::string("hello");
|
- No copy
- No move
- Direct construction in return location
❌ Wrong Optimization
1
2
3
4
5
| std::string create()
{
std::string s = "hello";
return std::move(s); // ❌ prevents copy elision
}
|
- Forces move → may be slower
Move Semantics (Caution)
✔ Good usage
1
| std::string s = std::move(temp);
|
❗ Overuse problem
Unnecessary std::move can:
- Disable copy elision
- Introduce extra move operation
“Faster in theory” ≠ “Faster in practice”
4. Best Practice
✔ Measure, don’t guess
- Benchmark with real data
- Use compiler-specific optimization flags
- Profile before and after
❌ Over-optimized (wrong)
✔ Better
1
| return obj; // let compiler optimize
|