When implementing algorithms, prioritize both correctness and performance by selecting appropriate data structures, optimizing memory usage, and leveraging language features.
When implementing algorithms, prioritize both correctness and performance by selecting appropriate data structures, optimizing memory usage, and leveraging language features.
Implement proper three-way comparisons that handle equality cases correctly:
// INCORRECT: Returns only -1 or 1, missing 0 for equality
inline int WeightedDeltaCompare(const void* const a, const void* const b) {
return (reinterpret_cast<const WeightedDelta*>(a)->delta -
reinterpret_cast<const WeightedDelta*>(b)->delta) <= 0 ? 1 : -1;
}
// CORRECT: Returns -1, 0, or 1 for proper ordering
inline int WeightedDeltaCompare(const void* const a, const void* const b) {
float delta_a = reinterpret_cast<const WeightedDelta*>(a)->delta;
float delta_b = reinterpret_cast<const WeightedDelta*>(b)->delta;
if (delta_a < delta_b) return -1;
if (delta_a > delta_b) return 1;
return 0;
}
Defer memory allocation until needed to avoid unnecessary resource consumption:
// INEFFICIENT: Creates vector regardless of whether it will be used
std::vector<std::uint16_t> uint16_data;
if (GetDataType() != QNN_DATATYPE_SFIXED_POINT_16) {
return;
}
// EFFICIENT: Only creates vector when it will be used
if (GetDataType() != QNN_DATATYPE_SFIXED_POINT_16) {
return;
}
std::vector<std::uint16_t> uint16_data;
Use std::iota for sequential initialization instead of manual loops:
// INEFFICIENT: Manual population of sequential values
std::vector<TypeParam> values;
for (int i = 0; i < 32768; i++) {
values.push_back(i);
}
// EFFICIENT: Use std::iota for sequential initialization
std::vector<TypeParam> values(32768);
std::iota(values.begin(), values.end(), TypeParam(0));
Use std::move when transferring collections to optimize performance:
// INEFFICIENT: Copying elements one by one
for (const auto& op_wrapper : op_wrappers) {
graph_op_wrappers.emplace_back(op_wrapper);
}
// EFFICIENT: Moving entire collection at once
std::move(op_wrappers.begin(), op_wrappers.end(),
std::back_inserter(graph_op_wrappers));
Ensure mathematical algorithms handle edge cases and are implemented according to their proper definitions:
// INCORRECT: Wrong implementation of floormod
// floormod(x,y) = (x/y) - floor(x/y)
// CORRECT: Proper implementation with additional multiplication
// floormod(x,y) = ((x/y) - floor(x/y))*y
Be vigilant about integer overflow, especially in calculations involving ranges or large numbers:
// VULNERABLE to overflow when limit-start is large
auto size_auto = Eigen::numext::ceil(Eigen::numext::abs((limit - start) / delta));
// SAFER approach to avoid overflow
auto size_auto = Eigen::numext::ceil(
Eigen::numext::abs((limit / delta) - (start / delta)));
Enter the URL of a public GitHub repository