在 c++ 中将值转换为范围内的值,使用 boost 或 std 进行优化
Posted
技术标签:
【中文标题】在 c++ 中将值转换为范围内的值,使用 boost 或 std 进行优化【英文标题】:Convert values to values inside a range in c++ , optimized using boost or std 【发布时间】:2014-07-16 01:19:28 【问题描述】:我想验证一个数组的所有元素。如果一个元素低于一个值,则交换一个最小值,如果它高于一个值,则交换一个最大值。
但我不知道如何优化它。为此,我逐个元素地遍历所有元素,但它没有优化,并且它在非常大的数组中花费了大量的 CPU 时间。
这是我的代码示例:
#include <iostream>
#include <math.h>
const int MAX = 10;
int main ()
float minVal = 2.0;
float maxVal = 11.0;
float vElem[] = -111111.0/0.0, 10.0, 90.0, 8.0, -7.0,
-0.6, 5.0, 4.0, 33.0, 222222222.0/0;
for(int i=0; i<MAX; i++)
if(isinf(vElem[i])==-1 || vElem[i]<minVal) vElem[i] = minVal;
if(isinf(vElem[i])==1 || vElem[i]>maxVal || isnan(vElem[i])) vElem[i] = maxVal;
std::cout << vElem[i]<< std::endl;
【问题讨论】:
我没有看到任何其他选项...您必须检查每个元素并根据您的逻辑决定要做什么。即使有一个花哨的 C++ 结构,它也会下划线做同样的事情(遍历所有元素并对其执行检查操作) 如果您有多个内核,您可以使用 OpenMP 或其他方式使用自动并行化。包括标题并将#pragma omp parallel for
放在循环上方
您可以访问哪个版本的 C++? (即,C++11 好吗?)
您的用例真的需要 I/O 吗?因为 I/O 开销胜过您在循环中所做的所有事情。
Most efficient/elegant way to clip a number?的可能重复
【参考方案1】:
我认为在这里使用复杂的构造不会给你带来太多好处。也许让你的代码更干净一点?
std::for_each(std::begin(vElem), std::end(vElem), [](float &val)
val = clamp(val, minVal, maxVal);
);
this 是典型的钳位函数返回的内容
【讨论】:
您说“精巧的构造不会 [不会] 给您买太多”,但您的代码比 OP 的代码大大干净(尽管std::transform
比 @987654324 更合适@)。
@KonradRudolph 是的,我指的是使用过滤提升范围等。没有使用transform
来避免指定result
迭代器;我同意它会清楚地传达意图
result
迭代器只是 std::begin(vElem)
: std::transform
可以就地工作。
这是个好主意,如果它不能t be optimize. I have g++ version 4.1.2, so I couldn
t 使用它,但我已经按照你的建议重写了它。我用过for_each,虽然我没有在我的项目中安装这个boost包,但我用过std::min(std::max(val, minVal), maxVal)而且更清楚
@user3480234 更新你的 GCC,它可悲过时了。【参考方案2】:
for(int i=0; i<MAX; i++)
float c = vElem[i];
//Could convert c to an integer here, so the below uses integer operations
//Additional cost is two multiplications (scaling up and scaling back down).
float n = c + ((c < min) * (min - c)) + ((c > max) * (max - c));
std::cout << n << std::endl;
两次乘法
四个补充
两个比较
我认为这比其他答案中提到的任何clamp()
实现都快。
【讨论】:
与整数类型的运算相比,浮点运算(四次加法,两次乘法,甚至两次比较)的成本很高。clamp()
函数只有两次比较,条件跳转。我的猜测是clamp()
函数更快。无论如何,没有板凳就无法知道。
链接到的答案是:return n = 上?上:n;这是三元运算符,表示条件分支。如果您从不需要分支 - 可能会更快,但如果您这样做了,性能成本将会非常高。
您可以在开始时将浮点数转换为整数,使用整数算术,然后将整数缩放回浮点数。以上是关于在 c++ 中将值转换为范围内的值,使用 boost 或 std 进行优化的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 stringstream 在 C++ 中将字符串转换为双精度值 [关闭]