int temp, i;
for ( i = 0; i < num_of_elements; i++ ){
temp = a[ i ];
a[ i ] = b[ i ];
b[ i ] = temp;
}
などと書くのはあまりに効率が悪い.
こういうときはaおよびbの先頭要素へのポインタpaおよびpbを用意しておき,
ポインタ同士を交換すればよい.
要素へのアクセスもポインタを用いる.
int *pa, *pb, *p;
pa = a; pb = b;
p = pa; pa = pb; pb = p;
以下のコードは要素数が10000の整数型配列aおよびbの要素を10000回交換し,
その都度全要素の和を求めるものである.
ポインタの交換ではなく,要素を直接交換している.
#include <stdio.h>
#include <windows.h>
#define num_of_elements 10000
int main(){
int a[ num_of_elements ], b[ num_of_elements ], temp;
int sum_a, sum_b, i, n;
DWORD started, terminated;
started = GetCurrentTime();
for ( i = 0; i < num_of_elements; i++ ){
a[ i ] = i + 1;
b[ i ] = ( i + 1 ) * 2;
}
for ( n = 1; n <= 10000; n++ ){
for ( i = 0; i < num_of_elements; i++ ){
temp = a[ i ];
a[ i ] = b[ i ];
b[ i ] = temp;
}
for ( i = 0, sum_a = 0, sum_b = 0; i < num_of_elements; i++ ){
sum_a += a[ i ];
sum_b += b[ i ];
}
}
terminated = GetCurrentTime();
printf( " total %10.3f seconds\n", ( terminated - started ) * 1e-3 );
return 0;
}
このコードをVisual C/C++ 5.0でコンパイルし,
PentiumIII 600MHzのbushで実行してみた.
3回実行して,それぞれに要した時間は5.117秒,5.097秒,5.108秒であった.
#include <stdio.h>
#include <windows.h>
#define num_of_elements 10000
int main(){
int a[ num_of_elements ], b[ num_of_elements ], temp, *pa, *pb, *p;
int sum_a, sum_b, i, n;
DWORD started, terminated;
started = GetCurrentTime();
for ( i = 0; i < num_of_elements; i++ ){
a[ i ] = i + 1;
b[ i ] = ( i + 1 ) * 2;
}
pa = a; pb = b;
for ( n = 1; n <= 10000; n++ ){
p = pa; pa = pb; pb = p;
for ( i = 0, sum_a = 0, sum_b = 0; i < num_of_elements; i++ ){
sum_a += pa[ i ];
sum_b += pb[ i ];
}
}
terminated = GetCurrentTime();
printf( " total %10.3f seconds\n", ( terminated - started ) * 1e-3 );
return 0;
}
こちらも3回実行し,それぞれに要した時間は2.174秒,2.183秒,2.193秒であった.
ポインタの交換にかかる時間は無視できるから,あとコードの実行時間は
配列aおよびbの初期化と和の計算に要した時間である.
この時間ははじめのコードでも同じはずだから,
全要素の直接交換からポインタを使った間接交換に
置き換えたことにより,実行時間を約60%も短くできたことになる.
ここに置いてある文書に載せた非定常熱伝達のコードは
配列要素を直接交換している.
ポインタの交換に置き換えた修正版を以下に示しておく.
#include <stdio.h>
#include <math.h>
#define NUM_STEPS 100
#define INIT_TEMP 1000
int main(){
double temp_a[ NUM_STEPS ], *pa, temp_b[ NUM_STEPS ], *pb, *p;
double alpha, time, x_step, time_step;
int n, i;
alpha = 6.6;
x_step = 1e1 / NUM_STEPS;
time_step = pow( x_step, 2 ) / 2e0 / alpha * 3.6e3;
pa = temp_a;
pb = temp_b;
time = 0;
for ( i = 0; i < NUM_STEPS; i++ ){
if ( i == 0 ){
pa[ i ] = 0;
pb[ i ] = 0;
}
else {
pa[ i ] = INIT_TEMP;
pb[ i ] = INIT_TEMP;
}
}
n = 1;
while ( pa[ 10 ] >= INIT_TEMP / 2 ){
time = time_step * n;
for ( i = 0; i < NUM_STEPS; i++ ){
switch( i ){
case 0:
pa[ i ] = 0;
break;
case NUM_STEPS - 1:
pa[ i ] = INIT_TEMP;
break;
default:
pa[ i ] = ( pb[ i - 1 ] + pb[ i + 1 ] ) / 2e0;
}
}
printf( "%d %10.3f %10.3f\n", n, time, pa[ 10 ] );
p = pb; pb = pa; pa = p;
n++;
}
return 0;
}
SEO | [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送 | ||