的std :: for_each的 [英] std::for_each

查看:61
本文介绍了的std :: for_each的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时我使用std :: for_each编写代码。有时我在

上使用几个相同大小的容器类。


for_each(v.begin(),v.end(),f1( ));

for_each(u.begin(),u.end(),f2());


这似乎效率低下所以我把它重写为:


int n = v.size();

for(int i = 0; i< n; ++ i)

{

f1(v [i]);

f2(u [i]);

}


是否有一些机制可以让我说出以下内容:


for_each((v.begin(),u.begin()),(v。 end(),u.end()),(f1(),f2()));


谢谢


-

sashan
http:// www.cs.auckland.ac.nz/~sgov008/

Sometimes I write code using std::for_each. Sometimes I use it on
several container classes that are the same size.

for_each(v.begin(), v.end(), f1());
for_each(u.begin(), u.end(), f2());

This seems inefficient so I rewrite it as:

int n = v.size();
for (int i = 0; i < n; ++i)
{
f1(v[i]);
f2(u[i]);
}

Is there some mechanism that lets me say the following:

for_each((v.begin(), u.begin()), (v.end(), u.end()), (f1(), f2()));

Thanks

--
sashan
http://www.cs.auckland.ac.nz/~sgov008/


推荐答案

" sashan" <毫安*** @ operamail.com>在消息中写道

news:bl ********** @ lust.ihug.co.nz ...
"sashan" <ma***@operamail.com> wrote in message
news:bl**********@lust.ihug.co.nz...
有时我使用std编写代码: :的for_each。有时我会在几个相同大小的容器类上使用它。

for_each(v.begin(),v.end(),f1());
for_each (u.begin(),u.end(),f2());

这似乎效率低下,所以我把它重写为:

int n = v.size( );;
for(int i = 0; i< n; ++ i)
{
f1(v [i]);
f2(u [i]) ;
}
Sometimes I write code using std::for_each. Sometimes I use it on
several container classes that are the same size.

for_each(v.begin(), v.end(), f1());
for_each(u.begin(), u.end(), f2());

This seems inefficient so I rewrite it as:

int n = v.size();
for (int i = 0; i < n; ++i)
{
f1(v[i]);
f2(u[i]);
}




是什么让你认为这更有效率?如果我不得不猜测,我会打赌你的第二个版本运行*慢*由于你正在减少的事实

内存位置在不同阵列之间来回跳跃和

功能。此外,通过每次索引到数组而不是使用简单地递增的

迭代器,您使编译器更难以优化顺序访问更加困难(如果你和v比一个矢量更少,或者比一个矢量更平凡,就像一个双端队员,你正在使它显着地变得更加困难)。当前的编译器应该能够优化掉

索引,但你肯定不会对编译器有任何好处。


Ken



What makes you think this is any more efficient? If I had to guess, I would
bet that your second version runs *slower* due to the fact you are reducing
memory locality jumping back and forth between the different arrays and
functions. Also, by indexing into the array each time instead of using the
iterators which can simply be incremented, you are making it more difficult
for the compiler to optimize your sequential access (if u and v are less
trivial than a vector, like perhaps a deque, you are making it significantly
more difficult). Current compilers should be able to optimize away the
indexing, but you certainly aren''t doing the compiler any favors.

Ken


看起来效率低下......你有证据证明它实际上是*效率低吗
你的特定情况需要
吗?


您不仅将两行代码转换为4+代码,而且已经用自定义for()循环替换了

众所周知的std :: for_each成语,每个人<查看此代码的
将需要花时间进行检查。


Dan


" sashan" <毫安*** @ operamail.com>在消息中写道

news:bl ********** @ lust.ihug.co.nz ...
"seems inefficient"...do you have proof that it actually *is* inefficient
for your particular case?

Not only have you turned two lines of code into 4+, but you''ve replaced the
well-known std::for_each idiom with a custom for() loop that everybody
looking at this code will have to take the time to inspect.

Dan

"sashan" <ma***@operamail.com> wrote in message
news:bl**********@lust.ihug.co.nz...
有时我使用std编写代码: :的for_each。有时我会在几个相同大小的容器类上使用它。

for_each(v.begin(),v.end(),f1());
for_each (u.begin(),u.end(),f2());

这似乎效率低下,所以我把它重写为:

int n = v.size( );;
for(int i = 0; i< n; ++ i)
{
f1(v [i]);
f2(u [i]) ;
}
是否有一些机制可以让我说出以下内容:

for_each((v.begin(),u.begin()),( v.end(),u.end()),(f1(),f2()));

谢谢

-
sashan
http://www.cs.auckland.ac.nz/ ~sgov008 /
Sometimes I write code using std::for_each. Sometimes I use it on
several container classes that are the same size.

for_each(v.begin(), v.end(), f1());
for_each(u.begin(), u.end(), f2());

This seems inefficient so I rewrite it as:

int n = v.size();
for (int i = 0; i < n; ++i)
{
f1(v[i]);
f2(u[i]);
}

Is there some mechanism that lets me say the following:

for_each((v.begin(), u.begin()), (v.end(), u.end()), (f1(), f2()));

Thanks

--
sashan
http://www.cs.auckland.ac.nz/~sgov008/



Ken Alverson写道:
Ken Alverson wrote:
" sashan" <毫安*** @ operamail.com>在消息中写道
新闻:bl ********** @ lust.ihug.co.nz ...

"sashan" <ma***@operamail.com> wrote in message
news:bl**********@lust.ihug.co.nz...

有时我会写使用std :: for_each的代码。有时我会在几个相同大小的容器类上使用它。

for_each(v.begin(),v.end(),f1());
for_each (u.begin(),u.end(),f2());

这似乎效率低下,所以我把它重写为:

int n = v.size( );;
for(int i = 0; i< n; ++ i)
{
f1(v [i]);
f2(u [i]) ;
}
Sometimes I write code using std::for_each. Sometimes I use it on
several container classes that are the same size.

for_each(v.begin(), v.end(), f1());
for_each(u.begin(), u.end(), f2());

This seems inefficient so I rewrite it as:

int n = v.size();
for (int i = 0; i < n; ++i)
{
f1(v[i]);
f2(u[i]);
}



是什么让你认为这更有效?



What makes you think this is any more efficient?



更少的比较和更少的增量,我想。


我附上了一个程序,使用上面的

方法对操作进行计时。在程序方法1中使用for_each算法,方法2

是上面的for循环,方法3是使用迭代器的for循环。

方法3是那种我最初的问题是针对的。

程序在std :: vector和方法1和3上测试方法1和2和3

在std :: list上(std :: list不支持随机访问,所以方法2

不起作用)。


请检查一下,告诉我是否有什么这是错的(也许我正在使用

QueryPerformance计数器错误或类似的东西)


总之,在发布版本中,方法1是最慢的方法2和

3是std :: vector最快的。对于std :: list方法3,

最快。使用vc7.1编译。

#include< iostream>

// #include< iomanip.h>

#include< math.h>

#include< windows.h>

#include< vector>

#include< functional>

#include< algorithm>

使用命名空间std;


struct Sqr:

unary_function< int,int>

{

void operator()(argument_type& i){i * = i;}

};


int vector_timing()

{

cout<< 矢量定时 << endl;

LARGE_INTEGER Freq,Start,End;

ZeroMemory(& Freq,sizeof(LARGE_INTEGER));

ZeroMemory(& Freq ,sizeof(LARGE_INTEGER));

ZeroMemory(& Freq,sizeof(LARGE_INTEGER));

BOOL有效= QueryPerformanceFrequency(& Freq);

如果(!有效)

返回-1;


//方法1

vector< int> u0(1000,3),v0(1000,3),w0(1000,3),x0(1000,3);

QueryPerformanceCounter(& Start);

for_each(u0.begin(),u0.end(),Sqr());

for_each(v0.begin(),v0.end(),Sqr());

for_each(w0.begin(),w0.end(),Sqr());

for_each(x0.begin(),x0.end(),Sqr()) ;

QueryPerformanceCounter(& End);

std :: cout<< 方法1 << End.QuadPart - Start.QuadPart<< endl;


//方法2

vector< int> u1(1000,3),v1(1000,3),w1(1000,3),x1(1000,3);

QueryPerformanceCounter(& Start);

vector< int> :: size_type n = u1.size();

for(int i = 0; i< n; ++ i)

{

Sqr()(u1 [i]);

Sqr()(v1 [i]);

Sqr()(w1 [i ]);

Sqr()(x1 [i]);

}

QueryPerformanceCounter(& End);

std :: cout<< 方法2 << End.QuadPart - Start.QuadPart<< endl;


//方法3

vector< int> u2(1000,3),v2(1000,3),w2(1000,3),x2(1000,3);

vector< int> :: iterator itu2,itv2,itw2,itx2 ;

QueryPerformanceCounter(& Start);

for(itu2 = u2.begin(),itv2 = v2.begin(),itw2 = w2.begin(), itx2 = x2.begin();

itu2!= u2.end();

++ itu2,++ itv2,++ itw2,++ itx2)

{

Sqr()(* itu2);

Sqr()(* itv2);

Sqr( )(* itw2);

Sqr()(* itx2);

}

QueryPerformanceCounter(& End);

std :: cout<< 方法3 << End.QuadPart - Start.QuadPart<<结束;

}


int list_timing()

{

LARGE_INTEGER Freq,Start,End ;

ZeroMemory(& Freq,sizeof(LARGE_INTEGER));

ZeroMemory(& Freq,sizeof(LARGE_INTEGER));

ZeroMemory (& Freq,sizeof(LARGE_INTEGER));

BOOL有效= QueryPerformanceFrequency(& Freq);

if(!Valid)

返回-1;


cout<< 列表定时 << endl;

//方法1

vector< int> u0(1000,3),v0(1000,3),w0(1000,3),x0(1000,3);

QueryPerformanceCounter(& Start);

for_each(u0.begin(),u0.end(),Sqr());

for_each(v0.begin(),v0.end(),Sqr());

for_each(w0.begin(),w0.end(),Sqr());

for_each(x0.begin(),x0.end(),Sqr()) ;

QueryPerformanceCounter(& End);

std :: cout<< 方法1 << End.QuadPart - Start.QuadPart<< endl;


//方法3

vector< int> u2(1000,3),v2(1000,3),w2(1000,3),x2(1000,3);

vector< int> :: iterator itu2,itv2,itw2,itx2 ;

QueryPerformanceCounter(& Start);

for(itu2 = u2.begin(),itv2 = v2.begin(),itw2 = w2.begin(), itx2 = x2.begin();

itu2!= u2.end();

++ itu2,++ itv2,++ itw2,++ itx2)

{

Sqr()(* itu2);

Sqr()(* itv2);

Sqr( )(* itw2);

Sqr()(* itx2);

}

QueryPerformanceCounter(& End);

std :: cout<< 方法3 << End.QuadPart - Start.QuadPart<<结束;

}


int main()

{

vector_timing();

list_timing();

返回0;

}


Less comparisons and less increments, I guess.

I''ve attached a program that times the operations using the above
methods. In the program method 1 uses the for_each algorithm, method 2
is a for loop like above and method 3 is a for loop using iterators.
Method 3 is the sort of thing I was aiming for with my initial question.
The program tests method 1 and 2 and 3 on std::vector and method 1 and 3
on std::list (std::list doesn''t support random access so method 2
doesn''t work).

Please check it and tell me if anything''s wrong (maybe I''m using
QueryPerformance counter wrong or something like that)

In summary, when in release build, method 1 is the slowest, method 2 and
3 are the fastest for std::vector. For std::list method 3 is the
fastest. Compiled using vc7.1.
#include <iostream>
//#include <iomanip.h>
#include <math.h>
#include <windows.h>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

struct Sqr :
unary_function<int,int>
{
void operator()(argument_type& i){i *= i;}
};

int vector_timing()
{
cout << "vector timing" << endl;
LARGE_INTEGER Freq, Start, End;
ZeroMemory(&Freq, sizeof(LARGE_INTEGER));
ZeroMemory(&Freq, sizeof(LARGE_INTEGER));
ZeroMemory(&Freq, sizeof(LARGE_INTEGER));
BOOL Valid = QueryPerformanceFrequency(&Freq);
if (!Valid)
return -1;

//method 1
vector<int> u0(1000,3),v0(1000,3),w0(1000,3),x0(1000,3);
QueryPerformanceCounter(&Start);
for_each(u0.begin(), u0.end(), Sqr());
for_each(v0.begin(), v0.end(), Sqr());
for_each(w0.begin(), w0.end(), Sqr());
for_each(x0.begin(), x0.end(), Sqr());
QueryPerformanceCounter(&End);
std::cout << "Method 1 " << End.QuadPart - Start.QuadPart << endl;

//method 2
vector<int> u1(1000,3),v1(1000,3),w1(1000,3),x1(1000,3);
QueryPerformanceCounter(&Start);
vector<int>::size_type n = u1.size();
for (int i = 0; i < n; ++i)
{
Sqr()(u1[i]);
Sqr()(v1[i]);
Sqr()(w1[i]);
Sqr()(x1[i]);
}
QueryPerformanceCounter(&End);
std::cout << "Method 2 " << End.QuadPart - Start.QuadPart << endl;

//method 3
vector<int> u2(1000,3),v2(1000,3),w2(1000,3),x2(1000,3);
vector<int>::iterator itu2, itv2, itw2, itx2;
QueryPerformanceCounter(&Start);
for (itu2 = u2.begin(), itv2 = v2.begin(), itw2 = w2.begin(), itx2 = x2.begin();
itu2 != u2.end();
++itu2, ++itv2, ++itw2, ++itx2)
{
Sqr()(*itu2);
Sqr()(*itv2);
Sqr()(*itw2);
Sqr()(*itx2);
}
QueryPerformanceCounter(&End);
std::cout << "Method 3 " << End.QuadPart - Start.QuadPart << endl;
}

int list_timing()
{
LARGE_INTEGER Freq, Start, End;
ZeroMemory(&Freq, sizeof(LARGE_INTEGER));
ZeroMemory(&Freq, sizeof(LARGE_INTEGER));
ZeroMemory(&Freq, sizeof(LARGE_INTEGER));
BOOL Valid = QueryPerformanceFrequency(&Freq);
if (!Valid)
return -1;

cout << "list timing" << endl;
//method 1
vector<int> u0(1000,3),v0(1000,3),w0(1000,3),x0(1000,3);
QueryPerformanceCounter(&Start);
for_each(u0.begin(), u0.end(), Sqr());
for_each(v0.begin(), v0.end(), Sqr());
for_each(w0.begin(), w0.end(), Sqr());
for_each(x0.begin(), x0.end(), Sqr());
QueryPerformanceCounter(&End);
std::cout << "Method 1 " << End.QuadPart - Start.QuadPart << endl;

//method 3
vector<int> u2(1000,3),v2(1000,3),w2(1000,3),x2(1000,3);
vector<int>::iterator itu2, itv2, itw2, itx2;
QueryPerformanceCounter(&Start);
for (itu2 = u2.begin(), itv2 = v2.begin(), itw2 = w2.begin(), itx2 = x2.begin();
itu2 != u2.end();
++itu2, ++itv2, ++itw2, ++itx2)
{
Sqr()(*itu2);
Sqr()(*itv2);
Sqr()(*itw2);
Sqr()(*itx2);
}
QueryPerformanceCounter(&End);
std::cout << "Method 3 " << End.QuadPart - Start.QuadPart << endl;
}

int main()
{
vector_timing();
list_timing();
return 0;
}


这篇关于的std :: for_each的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆