Загрузка данных
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <chrono>
#include <utility>
#include <algorithm>
#include <random>
using namespace std;
// Заполнение вспомогательного вектора случайными числами
void generate_random_data(vector<int>& arr)
{
mt19937 gen(12);
uniform_int_distribution<int> distrib(1, 1000000);
for (int i = 0; i < arr.size(); i++) {
arr[i] = distrib(gen);
}
return;
// создание генератора случайных чисел с фиксированным seed
// создание равномерного случайного распределения от 1 до 1000000
// заполнение массива числами из этого распределения
}
// 1. Сравнение push_back
pair<double, double> test_push_back(const vector<int>& data)
{
vector<int> v;
auto start_vec = chrono::high_resolution_clock::now();
//создание первой временной отметки - текущее время создание вектора
//в цикле по data заполнять созданный массив элементами из data с помощью push_back
for (int i = 0; i < data.size(); i++) {
v.push_back(data[i]);
}
auto end_vec = chrono::high_resolution_clock::now(); // создание второй временной отметки
double time_vec = chrono::duration_cast<chrono::microseconds>(end_vec - start_vec).count(); // разница между отметками в микросекундах (1 микросекунда = 10^(-6) секунд)
list<int> lst;
auto start_list = chrono::high_resolution_clock::now();
//создание первой временной отметки создание списка в цикле по data заполнять созданный список элементами из data с помощью push_back
for (int i = 0; i < data.size(); i++) {
lst.push_back(data[i]);
}
auto end_list = chrono::high_resolution_clock::now(); //создание второй временной отметки
double time_list = chrono::duration_cast<chrono::microseconds>(end_list - start_list).count(); // разница между отметками в микросекундах
return { time_vec, time_list }; // возвращает пару - время выполнения для вектора и списка
}
// 2. Сравнение push_front
pair<double, double> test_push_front(const vector<int>& data)
{
vector<int> v;
auto start_vec = chrono::high_resolution_clock::now();
// создание первой временной отметки создание вектора в цикле по data заполнять созданный массив элементами из data с помощью insert(в начало)
for (int i = 0; i < data.size(); i++) {
v.insert(v.begin(), data[i]);
}
// создание второй временной отметки
auto end_vec = chrono::high_resolution_clock::now();
// подсчет разницы между отметками в микросекундах для вектора
double time_vec = chrono::duration_cast<chrono::microseconds>(end_vec - start_vec).count();
list<int> lst;
auto start_list = chrono::high_resolution_clock::now();
// создание первой временной отметки создание списка в цикле по data заполнять созданный список элементами из data с помощью push_front
for (int i = 0; i < data.size(); i++) {
lst.push_front(data[i]);
}
auto end_list = chrono::high_resolution_clock::now();
double time_list = chrono::duration_cast<chrono::microseconds>(end_list - start_list).count();
return { time_vec, time_list };
}
// 3. Сравнение последовательного обхода (итерации)
pair<double, double> test_iteration(const vector<int>& data)
{
list<int> lst;
vector<int> v;
for (int i = 0; i < data.size(); i++) {
v.push_back(data[i]);
lst.push_back(data[i]);
}
// подсчет суммы:
volatile long long sum_vec = 0; // volatile защищает от оптимизации вырезания цикла
// создание первой временной отметки
auto start_vec = chrono::high_resolution_clock::now();
for (int i = 0; i < v.size(); i++) {
sum_vec += v[i];
}
// цикл по вектору для накапливания суммы в sum_vec
// создание второй временной отметки
auto end_vec = chrono::high_resolution_clock::now();
// подсчет разницы между отметками в микросекундах для вектора
double time_vec = chrono::duration_cast<chrono::microseconds>(end_vec - start_vec).count();
// Тест для std::list
volatile long long sum_list = 0;
// создание первой временной отметки
auto start_list = chrono::high_resolution_clock::now();
// цикл по списку для накапливания суммы в sum_list
for (auto it = lst.begin(); it != lst.end(); ++it) {
sum_list += *it;
}
// создание второй временной отметки
// подсчет разницы между отметками в микросекундах для списка
auto end_list = chrono::high_resolution_clock::now();
double time_list = chrono::duration_cast<chrono::microseconds>(end_list - start_list).count();
// вернуть пару - время выполнения для вектора и списка:
return { time_vec, time_list };
}
// 4. Сравнение сортировки
pair<double, double> test_sorting(const vector<int>& data)
{
list<int> lst;
vector<int> v;
for (int i = 0; i < data.size(); i++) {
v.push_back(data[i]);
lst.push_back(data[i]);
}
// создание первой временной отметки
auto start_vec = chrono::high_resolution_clock::now();
// сортировка вектора встроенной функцией std::sort(итератор начала, итератор конца)
sort(v.begin(), v.end());
// создание второй временной отметки
// подсчет разницы между отметками в микросекундах для вектора
auto end_vec = chrono::high_resolution_clock::now();
double time_vec = chrono::duration_cast<chrono::microseconds>(end_vec - start_vec).count();
// создание первой временной отметки
auto start_list = chrono::high_resolution_clock::now();
// сортировка списка встроенной функцией list.sort()
lst.sort();
// создание второй временной отметки
// подсчет разницы между отметками в микросекундах для списка
auto end_list = chrono::high_resolution_clock::now();
double time_list = chrono::duration_cast<chrono::microseconds>(end_list - start_list).count();
// вернуть пару - время выполнения для вектора и списка:
return { time_vec, time_list };
}
// Функция записи результатов в файл
void add_to_file(const vector<double>& res, int n, ofstream& file)
{
file << n << ";";
for (size_t k = 0; k < res.size(); k++)
file << int(res[k]) << ";"; // Запись в микросекундах
file << "\n";
}
int main()
{
// Сколько раз прогонять тест на каждом размере для усреднения случайных всплесков процессора
const int TEST_RUNS = 10;
pair<double, double> a;
// Файл 1: операции вставки в конец и обхода последовательности:
ofstream file_fast("push_back_and_iteration.csv"); // создание потока для записи в файл
file_fast << "size;vector_push_back;list_push_back;vector_iteration;list_iteration\n"; // создание первой строки в файле
for (int size = 10000; size <= 200000; size += 10000) // цикл по размерам последовательностей
{
vector<int> data(size); // создание вспомогательного вектора для хранения последовательности
// заполнение последовательности случайными значениями
double avg_v_pb = 0, avg_l_pb = 0; // avg_v_pb - время операции добавление в конец для вектора, avg_l_pb - для списка
double avg_v_it = 0, avg_l_it = 0; // avg_v_it - время обхода элементов последовательности для вектора, avg_l_it - для списка
for (int t = 0; t < TEST_RUNS; ++t) { // Повтор одинаковых операций на одних и тех же данных для усреднения случайных всплесков процессора
// сравнение времени выполнения операции добавления в конец
// накопление результатов в счетчиках avg_v_pb и avg_l_pb
// сравнение времени выполнения операции обхода элементов последовательности
// накопление результатов в счетчиках avg_v_it и avg_l_it
a = test_push_back(data);
avg_v_pb += a.first; avg_l_pb += a.second;
a = test_iteration(data);
avg_v_it += a.first; avg_l_it += a.second;
}
add_to_file({ avg_v_pb / TEST_RUNS, avg_l_pb / TEST_RUNS, avg_v_it / TEST_RUNS, avg_l_it / TEST_RUNS }, size, file_fast);
}
file_fast.close();
// Файл 2: операции вставки в начало :
ofstream file_front("push_front.csv");
file_front << "size;vector_push_front;list_push_front\n";
for (int size = 2000; size <= 30000; size += 2000)
{
// создание вспомогательного вектора для хранения последовательности
vector<int> data(size);
generate_random_data(data);
// заполнение последовательности случайными значениями
double avg_v_pf = 0, avg_l_pf = 0; // avg_v_pf - время выполнения операции добавления в начало для вектора, avg_l_pf - для списка
for (int t = 0; t < TEST_RUNS; ++t) {
a = test_push_front(data);
// сравнение времени выполнения операции добавления в начало
avg_v_pf += a.first; avg_l_pf += a.second;
// накопление результатов в счетчиках avg_v_pf и avg_l_pf
}
add_to_file({ avg_v_pf / TEST_RUNS, avg_l_pf / TEST_RUNS }, size, file_front);
}
file_front.close();
//Файл 3: операции сортировки :
ofstream file_sort("sorting.csv");
file_sort << "size;vector_sort;list_sort\n";
for (int size = 5000; size <= 50000; size += 5000)
{
vector<int> data(size);
generate_random_data(data);
double avg_v_sort = 0, avg_l_sort = 0; // avg_v_sort - время выполнения сортировки вектора, avg_l_sort - списка
for (int t = 0; t < TEST_RUNS; ++t) {
// сравнение времени сортировки
a = test_sorting(data);
// накопление результатов в счетчиках avg_v_sort и avg_l_sort
avg_v_sort += a.first; avg_l_sort += a.second;
}
add_to_file({ avg_v_sort / TEST_RUNS, avg_l_sort / TEST_RUNS }, size, file_sort);
}
file_sort.close();
return 0;
}