分享
 
 
 

valarray::apply()的批判

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

valarray::apply()的批判。

本人因恰好需要对数组做整体+=,-=,max等操作,发现valarray是一个挺好的东西,就用这个东西来帮助操作了。

然后发现了一个看上去更好的valarray::apply():它的描述是——把一个函数f的指针传给apply(),apply()就能返回一个被f作用过于每一个元素的valarray

就是说如果我想把一个数组a的每一个值乘以2得到一个新的数组,那么可以写成:

int f(int i)

{

return i * 2;

}

valarray<int>a(10);

valarray<int>b(10);

blahblah.../* 把a赋值为 {1,2,3,4,5,6,7,8,9,10}*/

b = a.apply(f); /*于是b就变成 {2,4,6,8,10,12,14,16,18,20}了*/

但是我对整个过程挺拿不准,写了一个constructor,copy constructor, operator = 都带有输出的类来检测,发现运行一次apply()就会调用很多次各种构造器和operator =()。于是打开<valarray>的源代码,发现这个apply()的定义是:

valarray<_Ty> apply(_Ty _F(_Ty)) const

{_VALOP(_Ty, size(), _F(_Ptr[_I])); }

#define _VALOP(TYPE, LENGTH, RHS) valarray<TYPE> _Ans(LENGTH); for (size_t _I = 0; _I < _Ans.size(); ++_I) _Ans[_I] = RHS; return (_Ans)

这样一看,我就认为apply()是一个效率非常低的东西了。因为为了做一个a的每个元素乘2得到的b,它会:

1.产生一个临时valarray: _Ans,长为10。

2.调用f()给_Ans的每一个元素赋值,循环10次。

3.return的时候产生再产生一个用来保存返回值的临时对象,大小也是10,并运行copy constructor将_Ans复制给它

4.再调用operator=()将刚才的临时返回值对象复制给b,循环10次。

其中又:

2.1 在调用f期间,如果f的传参数方式不是传引用,那么每call一次f调用一次copy constructor,在本例中为10次。

即使是传引用,因为这个引用是const,f中间也必须做一个临时的TYPE对象,还是要产生10次。

2.2 f的返回值必须是传值方式,于是f每返回一次又要生成一个临时返回值对象,调用一次copy constructor.合计10次。

2.3 把f的返回值传给_Ans,要调用TYPE::operator =(),又合计10次。

就是说为了把a全部10个元素每个乘2赋给已经初始化过的b,总计会产生10+10+10+10=40个临时对象,调用operator=()至少20次。再加上销毁对象的操作,额外开销相当大了。显然完全没有用循环来赋值合算。

(我很疑惑为什么apply()不定义成b.apply(f, a)的调用方式,而要写成b = a.apply(f)。如果用前面的方法可以节省中间的_Ans的产生,以及传递_Ans的返回值临时对象的产生。)

另外,apply()的这种形式也限制了不需要传参数与不需要返回值的操作的灵活性。

比如

1.要让a的所有成员赋为一个随机数,虽然可以写一个与传入值无关的f:

int f(int /* not used*/)

{

return rand();

}

但是写a = a.apply(f)的时候还是有很大浪费。

又如

2.我要输出a里所有的元素,那么定义f:

int f(int i)

{

cout << i << endl;

return i;

}

这样可以用a.apply(f)来执行,但是其中多做的返回值处理的操作又浪费了……

综上:我认为valarray::apply()从微观上来看是一个很不好的东东。但是就软件工程的观点来说,它用多余的4倍的损耗节省了开发者写一个循环的精力。所以我写这篇文章纯粹是开发时代的无病呻吟。

gambolgs April 23, 2005

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有