我很喜欢矢量.他们很快,很快.但我知道这个叫做valarray的东西存在.为什么我会使用valarray而不是矢量?我知道valarray有一些语法糖,但除此之外,它们什么时候有用?
请原谅我对valarray的问题.我正在尝试使用它,因为它在操作矢量和矩阵时非常类似于matlab.我首先做了一些性能检查,发现valarray无法实现stroustrup在c ++编程语言中声明的性能.
测试程序实际上做了双倍的5M乘法.我认为c = a*b至少可以与for循环双重型元素乘法相媲美,但我完全错了.试过几台电脑和vc6.0和vs2008.
顺便说一句,我使用以下代码在matlab上测试:
len = 5*1024*1024;
a = rand(len, 1);
b = rand(len, 1);
c = zeros(len, 1);
tic;
c = a.*b;
toc;
Run Code Online (Sandbox Code Playgroud)
结果是46ms.这个时间精度不高,仅作为参考.
代码是:
#include <iostream>
#include <valarray>
#include <iostream>
#include "windows.h"
using namespace std;
SYSTEMTIME stime;
LARGE_INTEGER sys_freq;
double gettime_hp();
int main()
{
enum { N = 5*1024*1024 };
valarray<double> a(N), b(N), c(N);
QueryPerformanceFrequency(&sys_freq);
int i, j;
for (j=0 ; j<8 ; ++j)
{
for (i=0 ; i<N ; ++i)
{
a[i] = rand();
b[i] …Run Code Online (Sandbox Code Playgroud) 我刚刚被以下内容灼伤。
如果我要初始化std::vector的n一个常量元素X我这样做:
std::vector<double> v(n, X);
Run Code Online (Sandbox Code Playgroud)
但是,如果我需要初始化std::valarray的n一个常量元素X我需要交换的大小和初始化常数:
std::valarray<double> va(X, n);
Run Code Online (Sandbox Code Playgroud)
在我看来,这就像一个任意的“陷阱”。
是否有技术原因或者决定有关的填充构造函数的参数的顺序时,当由标准委员会提供的一些设计原理std::vector,并std::valarray进行了规范?
为了加快库中的计算速度,我决定使用std::valarray该类。该文件说:
std :: valarray和helper类被定义为不包含某些形式的别名,因此可以优化对这些类的操作,类似于C编程语言中关键字limit的效果。此外,允许使用valarray参数的函数和运算符返回代理对象,以使编译器可以优化表达式,例如v1 = a * v2 + v3; 作为执行v1 [i] = a * v2 [i] + v3 [i]的单个循环;避免任何临时或多次通过。
这正是我所需要的。当我使用g ++编译器时,它的工作方式如文档中所述。我开发了一个简单的示例来测试std::valarray性能:
void check(std::valarray<float>& a)
{
for (int i = 0; i < a.size(); i++)
if (a[i] != 7)
std::cout << "Error" << std::endl;
}
int main()
{
const int N = 100000000;
std::valarray<float> a(1, N);
std::valarray<float> c(2, N);
std::valarray<float> b(3, N);
std::valarray<float> d(N);
auto start = std::chrono::system_clock::now();
d = a + b * …Run Code Online (Sandbox Code Playgroud) 我想迭代一个临时的valarray,但它不起作用.这是我的(非工作)代码:
#include <iostream>
#include <valarray>
int main()
{
using namespace std;
valarray<int> numerators = {99, 26, 25};
valarray<int> denominators = {9, 2, 5};
for (int i : numerators / denominators) { cout << i << ","; }
// lots of errors
return 0;
}
Run Code Online (Sandbox Code Playgroud)
下面是我想要实现的最小工作示例,除了我不想定义像这样的对象temp_array.
#include <iostream>
#include <valarray>
int main()
{
using namespace std;
valarray<int> numerators = {99, 26, 25};
valarray<int> denominators = {9, 2, 5};
valarray<int> && temp_array = numerators / denominators;
for (int i : …Run Code Online (Sandbox Code Playgroud) valarray类的外观的同时,以array一流的,可以请你解释我在哪里,我宁愿valarray过array反之亦然?
当我写一个简单的算术表达式valarray并将结果分配给auto我时,当我尝试访问gcc上的结果时,我得到一个段错误.
#include <iostream>
#include <valarray>
using std::ostream; using std::valarray;
ostream& operator<<(ostream&os, const valarray<double>&vs) {
os << "[";
for(auto&v : vs) os << v << " ";
return os << "]";
}
int main() {
valarray<double> a{ 1.0, 2.0, 3.0, 4.0 };
std::cout << "a: " << a << "\n";
valarray<double> b{ 2.0, 4.0, 6.0, 8.0 };
std::cout << "b: " << b << "\n";
valarray<double> c{ 2.0, 1.5, 0.5, 0.25 };
std::cout << "c: " << …Run Code Online (Sandbox Code Playgroud) 我std::valarray在Nicolai M. Josuttis写的一本C++书中读过.他在他的书"C++标准库"第17.4章中写道:
valarray类的设计并不是很好.事实上,没有人试图确定最终规范是否有效.发生这种情况是因为没有人对这些课程感到"负责".在标准完成之前很久就将valarray引入C++标准库的人离开了委员会.因此,很少使用valarrays.
那么,使用std::valarray哪个好主意?
考虑下面的MCVE,其中有两个值数组,其中w两次是两次v(在此处尝试):
#include <valarray>
using namespace std;
int main() {
valarray<int> v { 1, 2, 3 };
for ([[maybe_unused]] auto x : v) {} // Ok
auto w = v * 2; // Leads to failure in loop below
//valarray<int> w = v * 2; // Works
//auto w = v*=2; // Works
//auto w = v; w *= 2; // Works
for ([[maybe_unused]] auto x : w) {} // Failure here
}
Run Code Online (Sandbox Code Playgroud)
这个例子在最后一个循环中用clang和gcc编译失败(这里是gcc输出):
error: …Run Code Online (Sandbox Code Playgroud) 我有这段代码求和std::valarray<int>:
#include <iostream>
#include <valarray>
#include <vector>
int main()
{
std::vector<std::valarray<int>> vectorOfValarrays{{1, 1}, {2, 2}, {3, 3}};
std::valarray<int> sumOfValarrays(2);
for (const auto& i : vectorOfValarrays)
sumOfValarrays = sumOfValarrays + i;
std::cout << sumOfValarrays[0] << ' ' << sumOfValarrays[1];
}
Run Code Online (Sandbox Code Playgroud)
x86-64 gcc 12.2使用-O0and进行编译-O1,它会打印预期结果:
6 6
Run Code Online (Sandbox Code Playgroud)
3 3
Run Code Online (Sandbox Code Playgroud)
这可能是什么原因?我的代码是未定义的行为还是这是一个 gcc bug?