2016-06-24 2 views
0

Недавно я закончил писать то, что считаю своим кодом «main.cpp» в проекте консоли Win32. Он отлично разрабатывает решение, и внешняя версия выпуска работает и завершается в течение 30 секунд, что быстро для количества вычислений, которые она делает.C++ MFC медленное исполнение с 2D-вектором

Когда я использую свой встроенный пользовательский интерфейс MFC с помощью всего лишь 1 стандартного диалогового окна для некоторых простых входов с плавающей запятой, программа, которая сама по себе запускается, получает зависание, когда она должна создавать и вычислять некоторые 2D-векторы.

std::mt19937 generator3(time(0)); 
static uniform_01<std::mt19937> dist3(generator3); 

std::vector<int> e_scatter; 
for (int i = 0; i <= n; i++) 
{ 
    if (dist3() >= perc_e) 
    { 
     e_scatter.push_back(1); 
     // std::cout << e_scatter[i] << '\n'; 
     // system("pause"); 
    } 
    else 
    { 
     e_scatter.push_back(0); 
     // std::cout << e_scatter[i] << '\n'; 
     // system("pause"); 
    } 

} 
string fileName_escatter = "escatter.dat"; 
FILE* dout4 = fopen(fileName_escatter.c_str(), "w"); 
for (int i = 0; i <= n; i++) 
{ 
    fprintf(dout4, "%d", e_scatter[i]); 
    fprintf(dout4, "\n"); 
    // fprintf(dout2, "%f", e_scatter[i]); 
    // fprintf(dout2, "\n"); 
}; 
fclose(dout4); 

std::vector<vector<float>> electron; 
// std::vector<float> angle; 
**randutils::mt19937_rng rng2; 
std::vector<float> rand_scatter; 
for (int i = 0; i <= n; i++) 
{ 
    std::vector<float> w; 
    electron.push_back(w); 
    rand_scatter.push_back(rng2.uniform(0.0, 1.0)); 
    for (int j = 0; j <= 2000; j++) 
    { 
     if (e_scatter[i] == 0) 
     { 
      electron[i].push_back(linspace[j] * (cos((rand_scatter[i] * 90) * (PI/180)))); 
      //electron[i][j] == abs(electron[i][j]); 
     } 
     else 
     { 
      electron[i].push_back(linspace[j]); 
     }; 
    }; 
};** 

Более конкретно, он не проходит мимо определенного цикла, и я вынужден закрыть его. Я пропустил его на 20 минут, чтобы увидеть, будет ли он просто вычислять вещи медленнее, но все равно получает от него 0 выходных данных. Я не так хорош в части отладки кода, когда у меня есть этот графический интерфейс от MFC, так как у меня нет консоли, которая появляется.

Есть ли что-то, что мне не хватает, когда я пытаюсь использовать MFC для gui и больших 2D-векторов?

Первый цикл вычисляет и выдает выходной файл «escatter.dat» после его завершения, но второй набор циклов никогда не заканчивается, а использование памяти продолжает увеличиваться.

linspace [i] рассчитывается перед всем этим кодом и является всего лишь вектором номеров 2001 года, которые он использует для заполнения электронного вектора std :: vector> в двойном для циклов.

Ive включил это http://pastebin.com/i8A7t38K ссылку на часть MFC кода, который я использовал, чтобы не сделать это сообщение действительно долго читаемым.

спасибо.

+0

Предположение, что проект MFC компилируется в режиме отладки, который добавляет тонны чеков к вектору доступа. Это может легко превратить секунды в минуты. –

+0

Я совсем забыл об этом в режиме отладки. Вы на 100% правильны. Спасибо! – Kazkek

ответ

0

Я согласен с тем, что проверка отладки является основной проблемой. Но если ваша программа работает 30 секунд, n должно быть большим.

Вы можете оптимизировать свой код для уменьшения распределения памяти, предварительно распределяя память с помощью vector :: reserve;

std::vector<vector<float>> electron; 
// std::vector<float> angle; 
**randutils::mt19937_rng rng2; 
std::vector<float> rand_scatter; 
electron.reserve(n+1); // worth for big n 
rand_scatter.reserve(n+1); // worth for big n 
for (int i = 0; i <= n; i++) 
{ 
    std::vector<float> w; 
    electron.push_back(w); 
    rand_scatter.push_back(rng2.uniform(0.0, 1.0)); 
    electron[i].reserve(2000+1); // really worth for big n 
    for (int j = 0; j <= 2000; j++) 
    { 
     if (e_scatter[i] == 0) 
     { 
      electron[i].push_back(linspace[j] * (cos((rand_scatter[i] * 90) * (PI/180)))); 
      //electron[i][j] == abs(electron[i][j]); 
     } 
     else 
     { 
      electron[i].push_back(linspace[j]); 
     }; 
    }; 
};** 

или переписать не используя push_back (так как вы знаете, все размеры)

std::vector<vector<float>> electron(n+1); 
// std::vector<float> angle; 
**randutils::mt19937_rng rng2; 
std::vector<float> rand_scatter(n+1); 
for (int i = 0; i <= n; i++) 
{ 
    std::vector<float>& w=electron[i]; 
    w.reserve(2000+1); 
    float r=rng2.uniform(0.0, 1.0); 
    rand_scatter[i]=r; 
    for (int j = 0; j <= 2000; j++) 
    { 
     float f; 
     if (e_scatter[i] == 0) 
     { 
      f=linspace[j] * (cos((r * 90) * (PI/180))); 
      // f=abs(f); 
     } 
     else 
     { 
      f=linspace[j]; 
     }; 
     w[j]=f; 
    }; 
};** 

После этого среда может уменьшиться не более чем за несколько секунд.

Другая оптимизация

string fileName_escatter = "escatter.dat"; 
FILE* dout4 = fopen(fileName_escatter.c_str(), "w"); 
for (int i = 0; i <= n; i++) 
{ 
    fprintf(dout4, "%d\n", e_scatter[i]); // save one method call 
    // fprintf(dout2, "%f\n", e_scatter[i]); 
}; 
fclose(dout4); 

КСТАТИ: ofstream является СТЛ-способ записи файлов, как

ofstream dout4("escatter.dat", std::ofstream::out); 
for (int i = 0; i <= n; i++) 
{ 
    dout4 << e_scatter[i] << std::endl; 
}; 
dout4.close(); 
+0

Спасибо за это! Я хотел сделать оптимизацию после того, как у меня появилась первая работающая программа с интерфейсом. Теперь, когда проблема отладки была решена другими пользователями, эти оптимизации помогут мне! Я обнаружил, что ofstream был намного медленнее, чем fopen/fprintf, но другая часть поможет спасибо! – Kazkek

+0

Вы можете попробовать 'dout4 << e_scatter [i] <<" \ n ";' уменьшить флеши. – lexx9999

+0

Нет STL. И у меня полная потеря, почему вы считаете, что запуск большего количества кода, а не меньше, даст лучшую производительность. Потоки C++ по сути медленнее, чем прямой доступ к файлам. – IInspectable

Смежные вопросы