Visual Studio 2010 — C ++ Медленное время выполнения класса чтения сложных шаблонных изображений, с разделенным объявлением и реализацией

Я пытаюсь сделать двоичные файлы для чтения сложных изображений. Я использую VisualStudio 2010. ЗДЕСЬ code1:

      #include <stdio.h>
#include <conio.h>
#include <iostream>
#include <fstream>
#include <math.h>
#include <stdlib.h>
#define NX 21843
#define NY 22380
#include <windows.h>

class CTimer
{
public:
CTimer()
{
QueryPerformanceFrequency(&mqFreq);
}
~CTimer() {}

void Start()
{
QueryPerformanceCounter(&mqStart);
}
void End()
{
QueryPerformanceCounter(&mqEnd);
}
double GetTimeInSeconds()
{
return (mqEnd.QuadPart - mqStart.QuadPart)/static_cast<double>(mqFreq.QuadPart);
}
private:
LARGE_INTEGER mqStart;
LARGE_INTEGER mqEnd;
LARGE_INTEGER mqFreq;
};

using namespace std;

int main(void)
{
CTimer Time;
Time.Start();
ifstream INFILE;
INFILE.open("e:\\WORK\\CIMG.bindat", ios::binary);

short ***im_ptr;
im_ptr = new short** [2];
for (int i=0; i<2; i++){
im_ptr[i] = new short* [NX];
for (int j=0; j<NX; j++){
im_ptr[i][j] = new short [NY];
}
}

for(int i=0; i<2; i++){
for (int j=0; j<NX; j++){
for (int k=0; k<NY; k++){
int index = i*NY*NX + j*NY + k;
INFILE.read((char*)&im_ptr[i][j][k], sizeof(short));
if (index == 2*NX*NY-1){
INFILE.close();}
}
}
}

for (int i=0; i<2; i++){
for (int j=0; j<NX; j++){
delete[] im_ptr[i][j];
}
delete[] im_ptr[i];
}
delete[] im_ptr;

Time.End();
std::cout << Time.GetTimeInSeconds() << " seconds" << std::endl;
std::cout << "\nPress any key to exit" << std::endl;
getch();
return 0;

}

Этот код работает нормально, но только с изображениями типа SHORT.

Я решил сделать шаблон-класс, который позволяет читать изображения разных типов данных, и который разделяет декларацию и реализацию. Здесь code2:

stdafx.h — с объявлением моего класса

#pragma once

#include "targetver.h"
#include <stdio.h>
#include <tchar.h>

template<typename DataType>
class SARDataLoader
{
private:
int day,month,year;
public:
DataType*** LoadComplexImage(int, int);
int DeleteImageFromMemory(DataType***, int);
};

SARDataLoader_C.cpp — с реализацией моего класса

#include "stdafx.h"#include <iostream>
#include <fstream>
#include <stdlib.h>
using namespace std;

template<typename DataType>
DataType*** SARDataLoader<DataType>::LoadComplexImage(int NX, int NY){
using namespace std;
ifstream INFILE;
INFILE.open(""e:\\WORK\\CIMG.bindat"", ios::binary);
DataType ***im_ptr;
im_ptr = new DataType** [2];
for (int i=0; i<2; i++){
im_ptr[i] = new DataType* [NX];
for (int j=0; j<NX; j++){
im_ptr[i][j] = new DataType [NY];
}
}
for(int i=0; i<2; i++){
for (int j=0; j<NX; j++){
for (int k=0; k<NY; k++){
int index = i*NY*NX + j*NY + k;
INFILE.read((char*)&im_ptr[i][j][k], sizeof(DataType));
if (index == 2*NX*NY-1){
INFILE.close();}
}
}
}
return im_ptr;
};

template<typename DataType> int SARDataLoader<DataType>::DeleteImageFromMemory(DataType*** im_ptr, int NX){
for (int i=0; i<2; i++){
for (int j=0; j<NX; j++){
delete[] im_ptr[i][j];
}
delete[] im_ptr[i];
}
delete[] im_ptr;
return 112345;
};

template class SARDataLoader<short>;//explicit instantiation short

из MAIN.cpp — используя мой класс

#include "stdafx.h"#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <fstream>
#include <math.h>
#define NX 21843
#define NY 22380
#include <windows.h>

class CTimer
{
public:
CTimer()
{
QueryPerformanceFrequency(&mqFreq);
}
~CTimer() {}

void Start()
{
QueryPerformanceCounter(&mqStart);
}
void End()
{
QueryPerformanceCounter(&mqEnd);
}
double GetTimeInSeconds()
{
return (mqEnd.QuadPart - mqStart.QuadPart)/static_cast<double>(mqFreq.QuadPart);
}
private:
LARGE_INTEGER mqStart;
LARGE_INTEGER mqEnd;
LARGE_INTEGER mqFreq;
};

using namespace std;

int main(void)
{
CTimer Time;
Time.Start();
std::cout <<"\nIMAGE1 Loading..."<< std::endl;

SARDataLoader<short> IMG_LOADER;
short ***im_ptr = IMG_LOADER.LoadComplexImage(NX, NY);

int CODE = IMG_LOADER.DeleteImageFromMemory(im_ptr, NX);

Time.End();
double run_time = Time.GetTimeInSeconds();
std::cout <<CODE<<"\nRUNTIME "<<run_time<<" seconds"<<"\n...Press any key to exit...\n"<<std::endl;
getch();
return 0;

}

Этот код работает, и делает то же самое, что и code1.
Я использую CTimer-класс для code1 а также code2 измерение времени выполнения.
И это сказать, что code2 время выполнения почти в три раза медленнее, чем code1.
Может кто-нибудь сказать мне, что вызывает это и как решить эту проблему?

0

Решение

Глядя на код сборки, созданный двумя примерами (неоптимизированные компиляции), я заметил только два отличия:

  1. иметь дело с NX а также NY значения требуют фактических вычислений в шаблонной версии, потому что они передаются как параметры, а в исходном коде они были жестко запрограммированными константами (через #defineс). Однако объем работы, который был добавлен в шаблонный код, выглядел незначительным — я не могу себе представить, что они привели к ощутимой разнице во времени выполнения.

  2. шаблонный код вызывает деструктор для ifstream INFILE когда он вернется из LoadComplexImage() — время выполнения для этого включено в таймер в шаблонной версии. Поскольку дтор для INFILE не вызывается до main() возвращает в исходный код, который не включен во время для этого примера.

Я могу поверить, что Dtor для ifstream может занять измеримое количество времени (а то, что в библиотеке отладки может быть довольно медленным). Поскольку я не знаю, каковы сроки этих прогонов, я не знаю, будет ли это увеличивать на 200%. Но мне кажется, что это, вероятно, виновник, по крайней мере, большой части увеличения, если не всего.

Чтобы сравнить яблоки с яблоками, вам нужно перенастроить первоначальный тест, чтобы включить уничтожение INFILEили переместите открытие входного файла за пределы временного кода в обоих случаях и передайте его в шаблонную версию в качестве ссылки (или используйте глобальный для целей тестирования). Держать открытым & Закрытие входного файла за пределами временной области кажется лучшим выбором для сравнительного анализа этого материала.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector