函数调用的成本 [英] Costs of function calls

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

问题描述

大家好,

目前我正在调整我的一个项目,并想知道

高是调用(成员)函数的成本。我尝试了一些

possibilites并得出一个令人惊讶的结果。

也许有人可以向我解释一下我的测试可能有什么改进或者怎么样?
结果发生了吗?

对于测试,我评论了不同的线路。代码见下文。


问候,

Thomas Kowalski


// MS C ++ 8.0

// 1亿增加:

//简单的方法调用:2134毫秒,2123毫秒,

//内联呼叫:2037毫秒,2053毫秒,2073毫秒

//简单的方法参考参数:2153毫秒,2034毫秒,2093毫秒

//另外没有方法2034毫秒,2037毫秒,2032毫秒

//虚拟函数调用~2100 ms

//函数指针7060 ms,7260 ms,7260 ms


// gcc 3.3.6的结果类似但功能指针和普通电话一样快



#include" stdafx.h"

#include< ; iostream>

#include< cstdlib>

#include< vector>

#include< time.h>


使用命名空间std;


类摘要{

public:

virtual size_t add( size_t& a,size_t& b)= 0;

};


B级:公共摘要{

public:

virtual size_t添加(为size_t&安培; a,size_t& b);

};

C类:公共摘要{

public:

virtual size_t add(size_t& ; a,size_t& b);

};


D类:公共摘要{

public:

virtual size_t add(size_t& a,size_t& b);

};

/ ** /


class A {

public:

static size_t add(size_t& a,size_t& b);

};

//内联

内联size_t A :: add(size_t& a,size_t& b){

返回a + b;

};


size_t B :: add(size_t& a,size_t& b){

返回a + b;

};

size_t C :: add(size_t& a,size_t& b){

返回a + b;

};


size_t D :: add(size_t& a,size_t& b){

返回a + b;

};

int main(int argc,char * argv [])

{


//摘要* a =新D() ;

A a;

size_t(*加法)(size_t& ;,size_t&);

addition =& A :: add;

const size_t REPEAT = 1000000000;

size_t i,j, k;

j = 5;


clock_t start = clock();

for(i = 0; I< REPEAT; ++ i){

另外(i,k);

// k = a.add(i,j);

/ / k = i + j;

}

clock_t ende = clock();

cout<< K ist: << k<< endl;


cout<< 测试花了 << ((ende-start))<< " MS" <<结束;

cin> i;

返回0;

}

解决方案

Thomas Kowalski写道:


大家好,

目前我在调整其中一个我的项目,并想知道

高是如何调用(成员)函数的成本。我尝试了一些

possibilites并得出一个令人惊讶的结果。

也许有人可以向我解释一下我的测试可能有什么改进或者怎么样?
结果发生了吗?

对于测试,我评论了不同的线路。代码见下文。


问候,

Thomas Kowalski


// MS C ++ 8.0

// 1亿增加:

//简单的方法调用:2134毫秒,2123毫秒,

//内联呼叫:2037毫秒,2053毫秒,2073毫秒

//简单的方法参考参数:2153毫秒,2034毫秒,2093毫秒

//另外没有方法2034毫秒,2037毫秒,2032毫秒

//虚拟函数调用~2100 ms

//函数指针7060 ms,7260 ms,7260 ms


// gcc 3.3.6的结果是相似但功能指针一样快

正常通话


[..]



要创建内联与非内联的实际案例,您必须将

非内联成员函数放在单独的翻译单元中。否则

任何体面的编译器应该能够简单地内联你的所有电话,如果它可以看到实际的身体。


我_know_如果一个函数没有内联,它就会成本。建立

您的项目优化大小,使用''std :: vector''和它的

索引参数,你会注意到如果切换到索引

从指向第一个元素的指针代替,你将获得大量的b
性能提升。事实上,在某些情况下,最多十次。


V

-

请在通过电子邮件回复时删除资金''A'

我没有回复最热门的回复,请不要问


要创建内联与非内联的真实案例,您必须在单独的翻译单元中放置


非内联成员函数。否则

任何体面的编译器应该能够简单地内联你的所有调用,如果

它可以看到实际的身体。



好​​的,这是有道理的。但它如何内联虚拟函数调用?

摘要* a =新B();

a-> add(i,j);


这仍然可以内联吗?


我知道如果一个函数没有内联,它就会成本。建立

您的项目优化大小,使用''std :: vector''和它的

索引参数,你会注意到如果切换到索引

从指向第一个元素的指针代替,你将获得大量的b
性能提升。事实上,在某些情况下,最多十次。




你的意思是如果你有一个std :: vector并使用一个指向它的

值的指针,它的速度要快几倍元素然后使用

类型为int或unsigned int的索引?


非常感谢,

Thomas Kowalski


12月20日上午7:00,Thomas Kowalski < t ... @ gmx.dewrote:


我_know_如果一个函数没有内联,它就会costcha。建立

您的项目优化大小,使用''std :: vector''和它的

索引参数,你会注意到如果切换到索引

从指向第一个元素的指针代替,你将获得大量的b
性能提升。事实上,在某些情况下,最多十次。




你的意思是,如果你有一个std :: vector并使用指向它的

值的指针,它的速度要快几倍才能访问某个元素然后使用

类型为int或unsigned int的索引?



不,反过来说:


std :: vector< intvec;

//推送一些元素


int& a = vec [5]; //使用索引


int * ptr =&(vec [0]);

int& b = *(ptr + 5)//使用指针


第二个(使用指针)将比第一个(使用索引)更快

提供你不算把指针放在

的第一名。当优化循环遍历

时,这可能非常有用,例如:


int * ptr =&(vec [0]);

int size = vec.size();

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

* (ptr + i)+ = 2; //而不是vec [i] + = 2;


-

Erik Wikstr?m


Hello everybody,
currently I am tweaking a bit on one of my projects and wondered how
high are the costs for calling a (member) function. I tried some
possibilites and come to a suprising result.
Maybe someone can explain to me what I might improve on my test or how
come this results occured?
For testing I commented different lines out. Code see below.

Regards,
Thomas Kowalski

// MS C++ 8.0
// 1 Billion additions:
// simple methode call: 2134 ms, 2123 ms,
// inline call: 2037 ms, 2053 ms, 2073 ms
// simple methode ref param: 2153 ms, 2034 ms, 2093 ms
// addition no methode 2034 ms, 2037 ms, 2032 ms
// virtual funtion call ~2100 ms
// function pointer 7060 ms, 7260 ms, 7260 ms

// Results with gcc 3.3.6 are similar but function pointer are as fast
as normal calls

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <vector>
#include <time.h>

using namespace std;

class Abstract {
public:
virtual size_t add(size_t& a, size_t& b) = 0;
};

class B :public Abstract {
public:
virtual size_t add(size_t& a, size_t& b);
};
class C :public Abstract {
public:
virtual size_t add(size_t& a, size_t& b);
};

class D :public Abstract {
public:
virtual size_t add(size_t& a, size_t& b);
};
/**/

class A {
public:
static size_t add(size_t& a, size_t& b);
};
//inline
inline size_t A::add(size_t& a, size_t& b) {
return a+b;
};

size_t B::add(size_t& a, size_t& b) {
return a+b;
};
size_t C::add(size_t& a, size_t& b) {
return a+b;
};

size_t D::add(size_t& a, size_t& b) {
return a+b;
};
int main(int argc, char *argv[])
{

// Abstract* a = new D();
A a;
size_t (*addition)(size_t&, size_t&);
addition = &A::add;
const size_t REPEAT = 1000000000;
size_t i,j,k;
j=5;

clock_t start = clock();
for (i=0; i<REPEAT; ++i) {
addition(i, k);
// k = a.add(i,j);
// k = i+j;
}
clock_t ende = clock();
cout << "K ist: " << k << endl;

cout << "test took " << ((ende - start)) << " ms" << endl;
cin >i;
return 0;
}

解决方案

Thomas Kowalski wrote:

Hello everybody,
currently I am tweaking a bit on one of my projects and wondered how
high are the costs for calling a (member) function. I tried some
possibilites and come to a suprising result.
Maybe someone can explain to me what I might improve on my test or how
come this results occured?
For testing I commented different lines out. Code see below.

Regards,
Thomas Kowalski

// MS C++ 8.0
// 1 Billion additions:
// simple methode call: 2134 ms, 2123 ms,
// inline call: 2037 ms, 2053 ms, 2073 ms
// simple methode ref param: 2153 ms, 2034 ms, 2093 ms
// addition no methode 2034 ms, 2037 ms, 2032 ms
// virtual funtion call ~2100 ms
// function pointer 7060 ms, 7260 ms, 7260 ms

// Results with gcc 3.3.6 are similar but function pointer are as fast
as normal calls

[..]

To make a real case of inline versus non-inline, you _must_ place your
non-inlined member functions in a separate translation unit. Otherwise
any decent compiler should be able to simply inline all your calls if
it can see the actual body.

I _know_ that if a function is not inlined, it''s gonna costcha. Build
your project with optimization for size, use ''std::vector'' and its
indexing argument, and you''ll notice that if you switch to indexing
from a pointer to the first element instead, you''ll get plenty of
performance improvement. Up to ten times, as a matter of fact, in
some cases.

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask


To make a real case of inline versus non-inline, you _must_ place your

non-inlined member functions in a separate translation unit. Otherwise
any decent compiler should be able to simply inline all your calls if
it can see the actual body.

Ok, that makes sense. But how can it inline the virtual funtion call?
Abstract *a = new B();
a->add(i,j);

Can this still be inlined?

I _know_ that if a function is not inlined, it''s gonna costcha. Build
your project with optimization for size, use ''std::vector'' and its
indexing argument, and you''ll notice that if you switch to indexing
from a pointer to the first element instead, you''ll get plenty of
performance improvement. Up to ten times, as a matter of fact, in
some cases.

You mean that if you have an std::vector and use a pointer to its
values its several times slower to access a certain element then using
an index of type int or unsigned int?

Thanks a lot,
Thomas Kowalski


On Dec 20, 7:00 am, "Thomas Kowalski" <t...@gmx.dewrote:

I _know_ that if a function is not inlined, it''s gonna costcha. Build
your project with optimization for size, use ''std::vector'' and its
indexing argument, and you''ll notice that if you switch to indexing
from a pointer to the first element instead, you''ll get plenty of
performance improvement. Up to ten times, as a matter of fact, in
some cases.


You mean that if you have an std::vector and use a pointer to its
values its several times slower to access a certain element then using
an index of type int or unsigned int?

No, the other way around:

std::vector<intvec;
// Push some elements

int& a = vec[5]; // Using index

int* ptr = &(vec[0]);
int& b = *(ptr + 5) // Using pointer

The second (using pointer) will be faster than the first (using index)
provided that you don''t count the cost of getting the pointer in the
first place. This can be useful when optimising loops iterating over
all the elements in a vector like:

int* ptr = &(vec[0]);
int size = vec.size();
for (int i = 0; i < size; ++i)
*(ptr + i) += 2; // Instead of vec[i] += 2;

--
Erik Wikstr?m


这篇关于函数调用的成本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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