2011/07/10

『もったいない』を考えてみた。② ■■■

先回の続きです。ただし、今回取り上げる内容は、いろいろと問題がありますのでご了承ください。

メモリの視点から見ると・・・・

使う予定のないデータをメモリ上に保存しておくのは、非常にもったいないことです。そこで、膨大な配列数を持つ配列を最低限の配列数にまとめ、使い回す方法を試してみました。

使い回す方法① 要素のシフト

下図のように配列の要素をシフトさせて空いた場所に新たな要素を追加する方法。
hei
※上記はArray[8]を示し、数値が配列番号、英字が要素を示す。また、I、Jはそれぞれ新たな要素を示す。
コードで記載すると以下の様になります。
double Array[8];
bool newrecord; //更新の有無

if(newrecord){  //更新があれば
   for(int i=0;i<7;i++) Array[7-i] =Array[6-i];
} 
問題点
この方法は、ループ処理がなされるためCUP【CPU】に負荷が掛かります。その為、あまり良い方法とは言えません。

使い回す方法② ポイントのシフト

ポイント(代入先)のシフトをする方法を考えるために、脳内処理として配列の頭と最後をくっ付けてドーナッツ状にします。下図を参照(上記と同じ配列を使用) そして、一番古い要素のところに新しい要素を追加します。最後に、新しく代入した要素と一番古い要素との間を切り離せば脳内処理完了です。上記と同じ要素の並びが出来上がります。
maru
この方法を用いればループ処理を行わずに使い回しが可能になります。
コード表記すると以下のようになります。
double Array[8];
bool newrecord; //更新の有無
int zeroindex=0; //仮想配列番号
if(newrecord){  //更新があれば
  int index;   
  zeroindex++;
  index=7-zeroindex%8
  Arraay[index]=newdate//新しい要素の代入
} 
問題点
MQL4では試していませんが、MQL5だと55621回処理した後で【stack overflow】エラーを吐き出して強制終了場合(毎回ではありませんが・・・)があります。無限ループ対策に引っかかるのが原因でしょうか?そのため回避対策を施してやる必要が出てきます。

まとめ

今回の内容は、ほとんどの方にとってどうでもいいことだと思いますが、自分用の資料として記載しました。

2011/07/01

『もったいない』を考えてみた。 ■■■

節電が叫ばれる中、せっせとPCで遊んでいることに罪悪感を覚え今回は、コードの中に無駄なもの(不要なもの)がないか考えてみた。

CPUの視点から見ると・・・・

やはり一番の無駄は、不要なループ処理だと思います。本当にその処理にループ作業が必要か?または、そんなに多くのループ回数が必要か?2つの例を挙げて考えてみましょう!

合計の計算

簡単な合計計算コードを書いてみます。
//price[]は元データ
double SUM[100];
double goukei;
for(int i=0;i<100;i++){
  goukei=0;
  for(int k=0;k<100;k++) goukei+=price[i+k];//このループって必要なの?
  SUM[i]=goukei;
} 
上記のコードだと100×100で1万回ループすることになります。
合計を算出する場合に本当にこれだけのループ処理が必要なのでしょうか?
例えば以下の様なコードにすると、
//price[]は元データ
double SUM[100];
double goukei=0;
 for(int k=0;k<100;k++) goukei+=price[i+k];
 SUM[0]=goukei;
for(int i=1;i<100;i++) SUM[i]=SUM[i-1]-price[i-1]+price[i+99];
100+99で199回のループで済みます。98.01%の削減につながるわけです。
計算方法は、前回の合計から無くなる数を削除して、加わる数を足したものです。
簡単な方法ながら大幅なループの削減につながるわけです。

移動平均線の計算

EMAを使用すれば特に考える必要がありません。ちなみに、以下のコードが公式となります。
//price[]は元データ
double alfa//0<alfa<1のパラメータ
EMA[y]=alfa*price[x]+(1-alfa)*EMA[y-1];
SMAを使用する場合は、以下の様にするとループ数を削減できます。
//price[]は元データ
int period = 30;//適用期間のパラメータ
if(SMA[0]==0){
  double sum=0;
  for(int i=0;i<period;i++)sum+=price[i];
  SMA[0]=sum/period;
}else{
       SMA[y]=SMA[y-1]+(price[y+period-1]-price[y-1])/period;
       //若しくは
       //SMA[y]=(SMA[y-1]*period-price[y-1]+price[y+period-1])/period;
      }
合計計算の応用となるわけです。

まとめ

不要な処理をPCにさせることは、『もったいない』ことだと思います。
ちなみに、『スパコン 京』で最適化処理をしたらどうなるのだろう?なんて考えてしまいます。
OSにWindowsが使われているとは考えづらいですが・・・・
長くなりそうなので今回はここまで!気が向いたらまたこの続きを書きます。
搾電?ではなく節電思考でいきたいものです。(・・?