Append List to another list - c++

I have a large list<pair<T, T>>. To speed up my program i want to use different threads to fill up lists and then just connect them to 1 large list.
I found this solution: Basically same question
To test this solution, I created 2 lists with 2mio elements each and connected them like said.
list1.splice(list1.end(), list2);
But this operation lasts a few seconds and this seems a bit long for me to just adjust a few pointers.
So what is the correct way to connect 2 lists??
EDIT:
cout << "Filling matrix... ";
for(int i = 0; i < n; ++i) {
list1.push_back(make_pair(i, false));
list2.push_back(make_pair(i, false));
}
cout << "OK" << endl;
cout << "Merging lists... ";
clock_t begin = clock();
list1.splice(list1.end(), list2);
clock_t end = clock();
cout << "OK" << endl;
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << "Time: " << elapsed_secs << endl;
Output:
Filling matrix... OK
Merging lists... OK
Time: 4.54

Related

how to execute the running time of a program written in c++?

I have code that generates random numbers from 1-100 and sorts them using the merge sort which I already have in a separate function. Everything works but when I implement clock(); to try and get the running time, I always get zero. I have even tried with larger numbers like 10000 but still, the time passed always gives me zero. here is my code
int main() {
clock_t startTime;
clock_t endTime;
clock_t timePassed;
int array[100];
srand(time(NULL));
int n = sizeof(array) / sizeof(array[0]);
startTime = clock();
for (int j = 0; j < 100; j++)
{
array[j] = rand() % 100+1;
std::cout << array[j] << " ";
}
std::cout << "\n";
MergeSort(array, n);
std::cout << "After Merge Sort :" << std::endl;
PrintArray(array, n);
endTime = clock();
timePassed = ((endTime - startTime) / CLOCKS_PER_SEC);
std::cout << "\n" << timePassed;
}
return 0;
}
use
double timePassed = (endTime - startTime) / static_cast<double>(CLOCKS_PER_SEC);
Plan B for higher accuracy:
#include <iostream>
#include <chrono>
// ...
auto start_time{ std::chrono::high_resolution_clock::now() };
// ... code you want to time
auto end_time{ std::chrono::high_resolution_clock::now() };
std::cout << std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time).count() << ":";
std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count() << ":";
// ...
If you are developing on a Unix system and want to measure the execution time from an application, you can also use the 'time' command like:
time myapplication
see
time (Unix) - Wikipedia

Issues with program to test Shell, Insertion, and Quick sorts

So, this program is supposed to test run insertion, shell, and quick sorts with 3 different text files of integers, but for some reason beyond my understanding, none of the results short of the number of items is being displayed. It is supposed to show the number of seconds and clock cycles it takes to run each sort using clock(). Please, can anyone tell me why it isn't working? I am stumped!
#include "targetver.h"
#include <time.h>
#include <stdio.h>
#include <dos.h>
#include <iomanip>
#include <fstream>
#include <string>
#include <stdio.h>
#include <tchar.h>
#include <queue>
#include <stack>
#include <vector>
#include<iostream>
#include<cstdio>
#include<sstream>
#include<algorithm>
using namespace std;
// insertion sort function
void insertionSort(vector<int> arr, int n)
{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i - 1;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
// shell sort function
void shellSort(vector<int> arr, int n)
{
// Start with a big gap, then reduce the gap
for (int gap = n / 2; gap > 0; gap /= 2)
{
// Do a gapped insertion sort for this gap size.
// The first gap elements a[0..gap-1] are already in gapped order
// keep adding one more element until the entire array is
// gap sorted
for (int i = gap; i < n; i += 1)
{
// add a[i] to the elements that have been gap sorted
// save a[i] in temp and make a hole at position i
int temp = arr[i];
// shift earlier gap-sorted elements up until the correct
// location for a[i] is found
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)
arr[j] = arr[j - gap];
// put temp (the original a[i]) in its correct location
arr[j] = temp;
}
}
}
// function that swaps two elements
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition(vector<int> arr, int low, int high)
{
int pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high - 1; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++; // increment index of smaller element
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
/* The main function that implements QuickSort
arr --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(vector<int> arr, int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
// print array function
void printArray(vector<int> arr)
{
int z = arr.size();
int i;
for (i = 0; i < z; i++)
printf("%d ", arr[i]);
printf("n");
}
int main()
{
int max = 10000000;
vector<int> arr;
arr.reserve(max);
double start, end, elapsed_clock, elapsed_time;
int low, high, n;
string name;//holds first file name entered by user
ifstream fin;
cout << "Please enter the file name you wish to read from: ";//asks user for file name
getline(cin, name);//gets file name
fin.open(name);//opens file with set file name
if (fin.fail())//run if file name is incorrect or fails to load
{
cout << "Error opening " << name << "\n";//print error and file name
}
else
{
cout << "\nFile opened successfully, please wait." << endl;
// holds data read from file
int theData;
do // loop reads file till end
{
fin >> theData;
if (fin.good())
{
arr.push_back(theData);
}
//if read failed, check to see if file end was cause, otherwise print message and close
else if (!fin.eof())
{
cout << "\nThe file could not be read" << endl;
}
//runs while data being read
} while (!fin.eof());
}
fin.close();
n = sizeof(arr) / sizeof(arr[0]);
start = clock();
insertionSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Insertion Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
shellSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Shell Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
quickSort(arr, 0, n - 1);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Quick Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
printArray(arr);
cout << endl;//space
cout << "Please enter the file name you wish to read from: ";//asks user for file name
getline(cin, name);//gets file name
fin.open(name);//opens file with set file name
if (fin.fail())//run if file name is incorrect or fails to load
{
cout << "Error opening " << name << "\n";//print error and file name
}
else
{
cout << "\nFile opened successfully, please wait." << endl;
// holds data read from file
int theData;
do // loop reads file till end
{
fin >> theData;
if (fin.good())
{
arr.push_back(theData);
}
//if read failed, check to see if file end was cause, otherwise print message and close
else if (!fin.eof())
{
cout << "\nThe file could not be read" << endl;
}
//runs while data being read
} while (!fin.eof());
}
fin.close();
n = sizeof(arr) / sizeof(arr[0]);
start = clock();
insertionSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Insertion Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
shellSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Shell Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
quickSort(arr, 0, n - 1);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Quick Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
printArray(arr);
cout << endl;//space
cout << "Please enter the file name you wish to read from: ";//asks user for file name
getline(cin, name);//gets file name
fin.open(name);//opens file with set file name
if (fin.fail())//run if file name is incorrect or fails to load
{
cout << "Error opening " << name << "\n";//print error and file name
}
else
{
cout << "\nFile opened successfully, please wait." << endl;
// holds data read from file
int theData;
do // loop reads file till end
{
fin >> theData;
if (fin.good())
{
arr.push_back(theData);
}
//if read failed, check to see if file end was cause, otherwise print message and close
else if (!fin.eof())
{
cout << "\nThe file could not be read" << endl;
}
//runs while data being read
} while (!fin.eof());
}
fin.close();
n = sizeof(arr) / sizeof(arr[0]);
start = clock();
insertionSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Insertion Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
shellSort(arr, n);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Shell Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
start = clock();
quickSort(arr, 0, n - 1);
end = clock();
elapsed_clock = end - start;
elapsed_time = ((end - start) / CLK_TCK);
cout << "Quick Sort\t: " << arr.size() << " items" << " " << elapsed_clock << " ticks" << " " << elapsed_time << " sec\n";
printArray(arr);
cout << endl;//space
system("Pause");//waits for user input
return 0;
}
You should pass all vectors to function by reference, not by value.

C++ iterator in loop

+++ See update below +++
This is a code for reverse printing the content of an array. I used 3 slightly different methods for doing it: directly putting the dimension of the array in the for loop, using iterator and using reverse_iterator and measured the execution time of printing the for loop.
#include <iostream>
#include <vector>
#include <chrono>
using get_time = std::chrono::high_resolution_clock;
int main() {
std::cout << "Enter the array dimension:";
int N;
std::cin >> N;
//Read the array elements
std::cout << "Enter the array elements:" <<'\n';
std::vector <int> v;
int input;
for(size_t i=0; i<N; i++){
std::cin >> input;
v.push_back(input);
}
auto start = get_time::now();
for(int i=N-1; i>=0; i--){
std::cout << v[i] <<" ";
}
auto finish = get_time::now();
auto time_diff=finish-start;
std::cout << "Elapsed time,non-iterator= " << std::chrono::duration<double>
(time_diff).count() << " Seconds" << '\n';
auto start2 = get_time::now();
std::vector <int>::reverse_iterator ri;
for(ri=v.rbegin(); ri!=v.rend(); ri++){
std::cout << *ri <<" ";
}
auto finish2 = get_time::now();
auto time_diff2=finish2-start2;
std::cout << "Elapsed time, reverse iterator= " << std::chrono::duration<double>
(time_diff2).count() << " Seconds" << '\n';
auto start3 = get_time::now();
std::vector <int>::iterator i;
for(i=v.end()-1; i>=v.begin(); i--){
std::cout << *i <<" ";
}
auto finish3 = get_time::now();
auto time_diff3=finish3-start3;
std::cout << "Elapsed time, iterator= " << std::chrono::duration<double>
(time_diff3).count() << " Seconds" << '\n';
return 0;
}
The output is as follows:
Output:
5 4 3 2 1 Elapsed time,non-iterator= 2.7913e-05 Seconds
5 4 3 2 1 Elapsed time, reverse iterator= 5.57e-06 Seconds
5 4 3 2 1 Elapsed time, iterator= 4.56e-06 Seconds
My question is:
Why the direct method is almost 5 times slower than both iterator and reverse_iterator methods? Also, is this faster execution of iterator machine dependent?
This is a prototype, but I will need to deal with much bigger matrices; that is why I am asking this question. Thank you.
+++ Update +++
I am posting the updated results after incorporating the comments. It was too big for a comment.
I changed the for loop to evaluate the sum of an array with 100000 elements. I evaluated the same sum using the above mentioned methods (compiled with -O3 in clang++) and I have averaged the execution time for 3 methods over 10000 runs. Here are the results:
Average (10000 runs) elapsed time, non-iterator= 2.50183e-05
Average (10000 runs) elapsed time, reverse-iterator= 3.48299e-05
Average (10000 runs) elapsed time, iterator= 7.35307e-05
The results are much more uniform now, and now the non-iterator method is the fastest! Any insights? Or even this result is meaningless and I should do some more test?
the updated code:
#include <iostream>
#include <vector>
#include <chrono>
using get_time = std::chrono::high_resolution_clock;
int main() {
double time1,time2,time3;
int run=10000;
for(int k=0; k<run; k++){
//Read the array elements
std::vector <int> v;
int input,N=100000;
for(size_t i=0; i<N; i++){
v.push_back(i);
}
int sum1{0},sum2{0},sum3{0};
auto start = get_time::now();
for(int i=N-1; i>=0; i--){
sum1+=v[i];
}
auto finish = get_time::now();
auto time_diff=finish-start;
std::cout << "Sum= " << sum1 << " " << "Elapsed time,non-iterator= " << std::chrono::duration<double>
(time_diff).count() << " Seconds" << '\n';
auto start2 = get_time::now();
std::vector <int>::reverse_iterator ri;
for(ri=v.rbegin(); ri!=v.rend(); ri++){
sum2+=*ri;
}
auto finish2 = get_time::now();
auto time_diff2=finish2-start2;
std::cout << "Sum= " << sum2 <<" Elapsed time, reverse iterator= " << std::chrono::duration<double>
(time_diff2).count() << " Seconds" << '\n';
auto start3 = get_time::now();
std::vector <int>::iterator i;
for(i=v.end()-1; i>=v.begin(); i--){
sum3+=*i;
}
auto finish3 = get_time::now();
auto time_diff3=finish3-start3;
std::cout << "Sum= " <<sum3 << " Elapsed time, iterator= " << std::chrono::duration<double>
(time_diff3).count() << " Seconds" << '\n';
time1+=std::chrono::duration<double>(time_diff).count();
time2+=std::chrono::duration<double>(time_diff2).count();
time3+=std::chrono::duration<double>(time_diff3).count();
}
std::cout << "Average (" << run << " runs)" << " elapsed time, non-iterator= " << time1/double(run) <<'\n';
std::cout << "Average (" << run << " runs)" << " elapsed time, reverse-iterator= " << time2/double(run) <<'\n';
std::cout << "Average (" << run << " runs)" << " elapsed time, iterator= " << time3/double(run) <<'\n';
return 0;
}

Delete a pointer to C++ list is very very slow. Why?

I am trying to get rid of an STL list fast. So I have declared a pointer to that list.
I do the all manipulations and then I delete the pointer to free up the RAM.
But the process of deletion the pointer to the list is slow and as slow as when I do list.clear(). So it is very slow. Why does that happen? How can I delete the allocated RAM fast? When I am dealing with vector and deque the deletion is fast. Below is a program which demonstrates that.
//============//
// STL delete //
//============//
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <deque>
#include <cmath>
#include <iomanip>
#include <ctime>
using std::cout;
using std::cin;
using std::endl;
using std::list;
using std::vector;
using std::deque;
using std::fixed;
using std::setprecision;
using std::showpoint;
using std::sort;
// the main program
int main()
{
// variables and parameters
const long int I_MAX = static_cast<long int>(pow(10.0, 7.5));
const long int K_MAX = static_cast<long int>(pow(10.0, 6.0));
long int i;
long int k;
clock_t t1;
clock_t t2;
double tall;
// set the output
cout << fixed;
cout << setprecision(5);
cout << showpoint;
// main bench loop
for (k = 0; k < K_MAX; k++)
{
list<double> * listA = new list<double> [1];
vector<double> * vecA = new vector<double> [1];
deque<double> * deqA = new deque<double> [1];
cout << endl;
cout << "------------------------------->>> " << k << endl;
cout << endl;
// build the vector
t1 = clock();
cout << " 1 --> build the vector ..." << endl;
for (i = 0; i < I_MAX; i++)
{ vecA->push_back(static_cast<double>(cos(i))); }
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 2 --> done with the vector --> " << tall << endl;
// build the list
t1 = clock();
cout << " 3 --> build the list ..." << endl;
for (i = 0; i < I_MAX; i++)
{ listA->push_back(static_cast<double>(cos(i))); }
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 4 --> done with the list --> " << tall << endl;
// build the deque
t1 = clock();
cout << " 5 --> build the deque ..." << endl;
for (i = 0; i < I_MAX; i++)
{ deqA->push_back(static_cast<double>(cos(i))); }
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 6 --> done with the deque --> " << tall << endl;
// sort the vector
t1 = clock();
cout << " 7 --> sort the vector ..." << endl;
sort(vecA->begin(), vecA->end());
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 8 --> done with the vector --> " << tall << endl;
// sort the list
t1 = clock();
cout << " 9 --> sort the list ..." << endl;
listA->sort();
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 10 --> done with the list --> " << tall << endl;
// sort the deque
t1 = clock();
cout << " 11 --> sort the deque ..." << endl;
sort(deqA->begin(), deqA->end());
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 12 --> done with the deque --> " << tall << endl;
// delete the vector
t1 = clock();
cout << " 13 --> delete the vector ..." << endl;
delete [] vecA;
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 14 --> done with the vector --> " << tall << endl;
// delete the list
t1 = clock();
cout << " 15 --> delete the list ..." << endl;
delete [] listA;
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 16 --> done with the list --> " << tall << endl;
t1 = clock();
// delete the deque
cout << " 17 --> delete the deque ..." << endl;
delete [] deqA;
t2 = clock();
tall = (t2-t1)/static_cast<double>(CLOCKS_PER_SEC);
cout << " 18 --> done with the deque --> " << tall << endl;
}
int sentinel;
cin >> sentinel;
return 0;
}
Every element in the list has its own node, meaning an extra allocation which has to be freed.
If you want to get rid of it all really fast and use members with trivial destructors (no call needed), use a custom allocator for the list, which is optimized for that.
BTW: Allocating the container on the heap is a pessimisation.
Anyway, depending on your use-case another container like std::vector might make sense instead.
The problem is not so much deleting the list, as understanding how a list is represented as a chain of heap-allocated nodes.
So basically when you deleted the list, it also has to delete the ~30M nodes as well, which will absolutely be a noticeably slow operation.
Generally speaking a list is not a great container for small builtin types anyway due to the node overhead possibly taking more space than the data themselves.
Can you give us more information about the real problem you're trying to solve?

QueryPerformanceCounter returning negative number

Hey im trying to count how long the function takes to execute
I am doing it like this:
Timer.cpp
long long int Timer :: clock1()
{
QueryPerformanceCounter((LARGE_INTEGER*)&time1);
return time1;
}
long long int Timer :: clock2()
{
QueryPerformanceCounter((LARGE_INTEGER*)&time2);
return time2;
}
main.cpp
#include "Timer.h" //To allow the use of the timer class.
Timer query;
void print()
{
query.clock1();
//Loop through the elements in the array.
for(int index = 0; index < num_elements; index++)
{
//Print out the array index and the arrays elements.
cout <<"Index: " << index << "\tElement: " << m_array[index]<<endl;
}
//Prints out the number of elements and the size of the array.
cout<< "\nNumber of elements: " << num_elements;
cout<< "\nSize of the array: " << size << "\n";
query.clock2();
cout << "\nTime Taken : " << query.time1 - query.time2;
}
Can anyone tell me if i am doing this correctly?
You are substracting ending time from starting time.
cout << "\nTime Taken : " << query.time1 - query.time2;
should be
cout << "\nTime Taken : " << query.time2 - query.time1
Let's say I start something at 10 seconds and it finishes at 30 seconds. How long did it take? 20 seconds. To get that, we would do 30 - 10; that is, the second time subtract the first time.
So perhaps you want:
cout << "\nTime Taken : " << (query.time2 - query.time1);