如何在没有冗余计算的 if 语句中使用 std::valarray?
Posted
技术标签:
【中文标题】如何在没有冗余计算的 if 语句中使用 std::valarray?【英文标题】:How to use std::valarray in if statement without redundant computation? 【发布时间】:2020-05-31 15:09:44 【问题描述】:我有以下带有float
的代码,例如:
std::vector<float> v = 0.f, 1.f, 2.f;
for(size_t i = 0; i < v.size(); ++i)
if(v[i] != 0) // An optimization for `v[i] != 0`.
v[i] = v[i] * v[i] * v[i]; // Time-consuming computation.
现在我想用std::valarray<float>
替换float
:
using vfloat = std::valarray<float>;
std::vector<vfloat> v = vfloat0.f, 0.f, vfloat1.f, 0.f, vfloat2.f, 0.f;
for(size_t i = 0; i < v.size(); ++i)
// if(v[i] != 0) // I want this optimization! ◀◀◀◄◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀◀
v[i] = v[i] * v[i] * v[i]; // Time-consuming computation.
虽然新代码在逻辑上是正确的,但对于v[i][j] == 0
存在冗余计算。
那么如何在if
语句中使用std::valarray
而不进行冗余计算呢?
【问题讨论】:
“最佳”以什么方式?你面临什么问题?澄清。 你真的要开启警告 @AsteroidsWithWings 抱歉不清楚。现已更新。 使用嵌套循环 如果你问如何检查一个 valarray 是否包含非零元素:if ((v0[i] != 0).max())
【参考方案1】:
如果您想跳过 v[i]
中的元素,请使用嵌套循环
using vfloat = std::valarray<float>;
std::vector<vfloat> v = vfloat0.f, 0.f, vfloat1.f, 0.f, vfloat2.f, 0.f;
for(size_t i = 0; i < v.size(); ++i)
for(size_t j = 0; j < v[i].size(); ++j)
if (v[i][j] != 0)
v[i][j] = v[i][j] * v[i][j] * v[i][j]; // Time-consuming computation.
或apply
:
using vfloat = std::valarray<float>;
std::vector<vfloat> v = vfloat0.f, 0.f, vfloat1.f, 0.f, vfloat2.f, 0.f;
for(size_t i = 0; i < v.size(); ++i)
v[i] = v[i].apply([](float n) -> float
if (n == 0) return 0;
return n * n * n; // Time-consuming computation.
);
如果你想跳过v
中的元素
using vfloat = std::valarray<float>;
std::vector<vfloat> v = vfloat0.f, 0.f, vfloat1.f, 0.f, vfloat2.f, 0.f;
for(size_t i = 0; i < v.size(); ++i)
if ((v[i] != 0).max() != 0)
v[i] = v[i] * v[i] * v[i]; // Time-consuming computation.
【讨论】:
【参考方案2】:有很多选择:
#include <valarray>
#include <algorithm>
// 2 loops in the worst case
bool is_not_zero_0(std::valarray<float> const & v)
return v.max() != 0.0 || v.min() != 0.0;
// one loop
bool is_not_zero_1(std::valarray<float> const & v)
return std::find_if(v.begin(), v.end(v), [](float item)return item != 0.0f;) != v.end();
// 2 loops + allocation
bool is_not_zero_2(std::valarray<float> const & v)
return (v != 0.0).max();
【讨论】:
以上是关于如何在没有冗余计算的 if 语句中使用 std::valarray?的主要内容,如果未能解决你的问题,请参考以下文章