2011-02-12 8 views
1

私がすでに提出した大学での練習では、画像の名前がたくさんある.txtファイル(各行に1本)を読む必要がありました。 次に、各画像をASCIIファイルとして開き、データ(ppm形式の画像)を読み込み、一連の処理を行う必要がありました。 私のプログラムは、私がやっていた他の計算ではなく、ファイル部分のデータを読み込むのに時間の70%を費やしていたことに気付きました(ハッシュテーブルで各ピクセルの繰り返し回数を見つけ、 diferentsピクセルbeetween 2イメージなど..)、私は非常に奇妙なことを言い表すのは非常に奇妙であった。多くのASCIIファイルからデータを読み込む最速の方法

これは、PPM形式はどのように見えるかです:これは私がファイルからデータを読んでいた方法です

P3 //This value can be ignored when reading the file, because all image will be correctly formatted 
4 4 
255 //This value can be also ignored, will be always 255. 
0 0 0 0 0 0 0 0 0 15 0 15 
0 0 0 0 15 7 0 0 0 0 0 0 
0 0 0 0 0 0 0 15 7 0 0 0 
15 0 15 0 0 0 0 0 0 0 0 0 

ifstream fdatos; 
fdatos.open(argv[1]); //Open file with the name of all the images 

const int size = 128; 
char file[size]; //Where I'll get the image name 

Image *img; 
while (fdatos >> file) { //While there's still images anmes left, continue 
    ifstream fimagen; 
fimagen.open(file); //Open image file 
img = new Image(fimagen); //Create new image object with it's data file 
    ……… 
    //Rest of the calculations whith that image 
    ……… 
delete img; //Delete image object after done 
    fimagen.close(); //Close image file after done 
} 

fdatos.close(); 

と画像オブジェクトの内部には、このようなデータをお読みください。

const int tallafirma = 100; 
char firma[tallafirma]; 
fich_in >> std::setw(100) >> firma; // Read the P3 part, can be ignored 

int maxvalue, numpixels; 
fich_in >> height >> width >> maxvalue; // Read the next three values 
numpixels = height*width; 
datos = new Pixel[numpixels]; 

int r,g,b; //Don't need to be ints, max value is 256, so an unsigned char would be ok. 
for (int i=0; i<numpixels; i++) { 
    fich_in >> r >> g >> b; 
    datos[i] = Pixel(r, g ,b); 
} 
//This last part is the slow one, 
//I thing I should be able to read all this data in one single read 
//to buffer or something which would be stored in an array of unsigned chars, 
//and then I'd only need to to do: 
//buffer[0] -> //Pixel 1 - Red data 
//buffer[1] -> //Pixel 1 - Green data 
//buffer[2] -> //Pixel 1 - Blue data 

どのようなアイデアですか?私は1つのコールで配列全体を読んでかなり改善できると思いますが、どうしたのか分かりません。

また、「インデックスファイル」に含まれる画像の数を知ることは可能でしょうか?ファイルの行数を知ることは可能ですか(1行に1つのファイル名があるためです)

ありがとう!!

編集:これは私が時間をどのように味わっているかです。

#include <sys/time.h> 
#include <sys/resource.h> 
double get_time() 
{ 
    struct timeval t; 
    struct timezone tzp; 
    gettimeofday(&t, &tzp); 
    return t.tv_sec + t.tv_usec*1e-6; 
} 

double start = get_time(); 
//Everything to be measured here. 
double end = get_time(); 

cout << end-start << endl; 
+0

まあ、私はこの科目の講義と、この学生が参加しているプログラミングコンテストの主催者の1人です。自由にお手伝いしますが、学生が自分でコンテストを解決したり、さまざまなプログラミングソースを読んだり、コミュニティにアクティブなクエリを使用したりしていないとします。 とにかく私はこのクエリを検出したので、他の参加者ができ、コピーは完全に禁止されています........ –

答えて

1

メモリを割り当ててループごとに削除しています。あなたがパフォーマンスについて心配しているなら、それは良いとは思わない。

あなたができる改善点は、は、プログラムに割り当てられたメモリを再利用することです

datos = new Pixel[numpixels]; 

そして最後に、代わりの画像にコピーその後、ローカル変数にRGBを読ん:

void *memory = malloc(sizeof(Image)); //reusable memory. 

//placement new to construct the object in the already allocated memory! 
img = new (memory) Image(fimagen); 

//... 

img->~Image(); //calling the destructor 

//when you're done free the memory 
free(memory); //use free, as we had used malloc when allocating! 

同様に、あなたは特に、このラインで、Imageクラスのメモリを再利用することができますデータはそれほどエレガントではないので、ここでも少し改善することができます。

//this is yours : temporaries, and copying! 
fich_in >> r >> g >> b; 
datos[i] = Pixel(r, g ,b); 

//this is mine : no temporaries, no copying. directly reading into image data! 
fich_in >> datos[i].r >> datos[i].g >> datos[i].b; 

これらの他にも、私はあなたのコードパフォーマンスを賢明に改善する余地はないと思います!

+0

まあ、私は実際にそれを行うことができるか分かりませんでした。それが何かを助けるかどうか試してみるつもりです。また、私はそれほど心配していません。ただ気づいただけで、人々がバッファ全体にファイルを読んでいるのを見ましたが、ディスクに一度だけアクセスすることができますので、改善するでしょう。知っている。 – asendra

+1

さて、@ナワズ、それだった!一時変数とRGB変数へのコピーを行います。小さなセット(30の256x256イメージ)でテストすると、時間が0.23から0.098に減少します。聖なる煙xD – asendra

+0

@Alsenes:おめでとう! :-) – Nawaz

0

ファイル全体を読み取らずにテキストファイル内の行数を計算することはできません。

他の最適化については、コマンド(Unix/Linuxの場合)を使用して、プログラムが "wallclock"時間(合計時間プロセスの開始と終了の間)。もしそうでなければ、おそらくディスクやネットワークを待っているでしょう。

+0

さて、私はどこかでこのメソッドを使って時間を測定します。 – asendra

+0

このメソッドは何をしますか?時計の時間を得る、計算する、時計の時間を得る、違いを報告する? –

+0

私は編集していましたが、私は使用している方法で賢さを更新しました。 – asendra

関連する問題