为什么std::valarray会很慢。

本文作者通过对比实验发现,std::valarray在执行计算时的性能显著低于普通循环和直接使用指针访问。尽管std::valarray提供了丰富的操作,但在VCdebug模式下,由于额外的检查导致性能下降。后续文章将探讨优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(sguox002原创作品,欢迎批评,转载请保留作者信息)

std::valarray有着很多吸引人的特性。比如下标数组,切割,逻辑,算术运算。我们慢慢学习。

在这之前,我想看一下这个类的性能如何,因此我编了一个小程序,来做同样的计算。结果发现valarray要比普通的循环要慢得多。我将会在另一片文章中说明如何解决这个问题。

#include <iostream>

#include <valarray>
#include <iostream>
#include "windows.h"


using namespace std ;


class hptime
{
LARGE_INTEGER sys_freq;
public:
hptime(){QueryPerformanceFrequency(&sys_freq);}   


double gettime()
{
LARGE_INTEGER tick;
QueryPerformanceCounter(&tick);
return (double)tick.QuadPart*1000.0/sys_freq.QuadPart;
}
};


int main()
{
hptime t0;
    enum { N = 5*1024*1024 };
    valarray<double> a(N), b(N), c(N) ;
    int i,j;
    for(  j=0 ; j<8 ; ++j )
    {
        for(  i=0 ; i<N ; ++i ) 
        {
            a[i]=rand();
            b[i]=rand();
        }


        double* a1 = &a[0], *b1 = &b[0], *c1 = &c[0] ;
        double dtime=t0.gettime();
        for(  i=0 ; i<N ; ++i ) c1[i] = a1[i] * b1[i] ;
        dtime=t0.gettime()-dtime;
        cout << "double operator* " << dtime << " ms\n" ;


        dtime=t0.gettime();
        c = a*b ;
        dtime=t0.gettime()-dtime;
        cout << "valarray operator* " << dtime << " ms\n" ;


        dtime=t0.gettime();
        for(  i=0 ; i<N ; ++i ) c[i] = a[i] * b[i] ;
        dtime=t0.gettime()-dtime;
        cout << "valarray[i] operator* " << dtime<< " ms\n" ;


        cout << "------------------------------------------------------\n" ;
    }

}


打开优化运行结果为:

double operator* 60.655 ms
valarray operator* 149.445 ms
valarray[i] operator* 37.7197 ms
------------------------------------------------------
double operator* 33.4131 ms
valarray operator* 113.355 ms
valarray[i] operator* 37.4807 ms
------------------------------------------------------
double operator* 32.4348 ms
valarray operator* 111.492 ms
valarray[i] operator* 38.5 ms
------------------------------------------------------
double operator* 32.9003 ms
valarray operator* 112.317 ms
valarray[i] operator* 37.0661 ms
------------------------------------------------------


这个程序中有几点值得指出:

1。类的私有成员仍然可以通过指针直接存取,C++只是提供编译时的存取控制,从概念上实现封装,但是它不能防止任何运行时的存取。

2。VCdebug模式的运行结果更慢,可能10倍以上。是因为类里的assert等检查都会严重影响性能。(The reason of slowness stated here is not true in this case, see the other article Debug&Release for details-----by the author)

3。高精度时钟,其精度在微秒。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值