忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

一時オブジェクトの発生を気にする

STLやDirectXなどを使い出すと意外な所で一時オブジェクトが発生しています。
今日はD3DXVECTOR3の隠れた一時オブジェクトを紹介します。

拍手[0回]


①と②どっちが早いでしょう~?

D3DXEVCTOR3 v,v1,v2;


v=v1+v2;


v+=v1;
v+=v2;



---解説---
①の場合
D3DXVECTOR3のoperator+が呼ばれます。
D3DXVECTOR3 D3DXVECTOR3::operator+(const D3DXVECTOR3& vec)
{
 return D3DXVECTOR3(this->x+vec.x,this->y+vec.y,this->x+vec.y);
}
D3DXVECTOR3の一時オブジェクトがreturn文の所でよばれてしまい、
インスタンスが発生するとともに、D3DXVECTORのコンストラクタが呼ばれます。
コンストラクタの引数でthis->x+vec.xでも計算結果が発生します。

②の場合
D3DXVECTOR3& D3DXVECTOR3::operator += ( const D3DXVECTOR3& v )
{
    this->x += v.x;
    this->y += v.y;
    this->z += v.z;
    return *this;
}

D3DXVECTOR3の一時オブジェクトの発生しないです。

ということで②が早いです。

早くなるのは確かですが、ほんの少しです。毎ループするところとかはちょっと意識するのもいいですね。



ここからが本題です。GESリーダの本気です。
これから紹介する内容は難しい所があります

v=v1+v2;
をD3DXVECTOR3の一時オブジェクトが発生しないような方法があります。
その名は式テンプレート
式の情報をクラスとして保持し、=が呼ばれたときに初めて計算を始める遅延評価的なことをしていきたいとおもいます。
まずはじめにデフォルトの仕様から、
v=v1+v2; 
これはv1がoperator+を呼び出し、足し算した結果をD3DXVECTOR3として返します。
v=(D3DXVECTOR3);
こういう感じです。

今回はこうなります。
v=(VPlus);
自分とは違う型を返しているところが違和感であり、ポイントです。

では解説してきます。

class CVector3 : public D3DXVECTOR3
{
public:
  VPlus operator+(CVector3 _r){  retrun VPlus(*this,_r); }
  
  template<class T> CVector3& CVector3::operator=(const T& _vp)
  {
   _vp.ret(*this);
   return *this;
  }
 static void Plus( CVector3& _dest,  const CVector3& _l,  const CVector3& _r)
  {
   _dest.x+=_l.x+_r.x;
   _dest.y+=_l.y+_r.y;
   _dest.z+=_l.z+_r.z;
  }
};

class VPlus
{
private:
    const CVector3& m_l;
    const CVector3& m_r;
public:
    VPlus(const CVector3& _l, const CVector3& _r):
 m_l(_l),m_r(_r){}
    void ret(CVector3& dest) const
    {
        CVector3::Plus( dest,m_l, m_r );
    }
};

CVector3のoperator+が呼ばれた時にVPlusを返し、=が呼ばれた時ret関数を呼び初めて計算しています。
こうすることによってD3DXVECTOR3の一時オブジェクトが発生しなくなりました。
現状だと、この実装をしないほうが早くなるし、v=v1+v2+v3;でコンパイルエラーになります。
あくまで式テンプレートの触りだけを紹介しました。
もっと詳しく知りたい方は「http://homepage1.nifty.com/herumi/prog/prog81.html
私はここで勉強しました。
boostのprotoで式テンプレートを作る際の補助ライブラリとして提供されているそうです。


以上誰得情報でした~。
byリーダ和田
PR

COMMENT

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

No Title

  • by 結構前の副部長
  • 2012/12/09(Sun)21:47
  • Edit
新しくC++0x(C++11)にて、右辺値参照が追加され、上記関連の実装が楽になるようです。
他にもラムダ式や、バグをなくさせるための工夫など、色々有用なものが増えているみたいです。
業界もこちらに移っていきそうですね。

No Title

  • by リーダ和田
  • 2012/12/13(Thu)23:40
  • Edit
先日はありがとうございました。
「右辺値参照」なんですか
「不変値参照」と聞き間違えていて出ないなと困ってました

いつになるかわからないですが、
また会える日を楽しみにしています!

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]