Significant runtime increase after employing list::size() - c++

I have a huge code size. I recently added some new code and it works fine until I added a new simple if statement. After adding this add statement the runtime increases by 100X which is nonsense.
Some part of my code is below. The if statement is added in terminate_ongoing function and even if I remove everything inside if statement, the program is still slow. But if I comment this if statement, it becomes fast again.
The if statement is
if ( emitted_vulnerable_list.size() > 100000 ){
}
As you can see, I removed everything inside if, but the problem is not resolved. Could you please provide some hints to find the source of problem and solve it.
class flip_flop_vulnerable_time{
public:
list <vulnerable_time> emitted_vulnerable_list;
list <vulnerable_time> ongoing_vulnerable_list;
void terminate_ongoing(int PO, int minimum_delay , int cycle, long long elimination_time){
for (list<vulnerable_time>::iterator it=ongoing_vulnerable_list.begin(); it!=ongoing_vulnerable_list.end(); it++){
if ( it-> PO_signal_number == PO && it->cycles_passed == cycle && it->min_delay == minimum_delay ){
it-> elimination_time = elimination_time;
if ( cycle == 0 && elimination_time - it->appearance_time < 500 )
ongoing_vulnerable_list.erase(it);
else{
emitted_vulnerable_list.splice(emitted_vulnerable_list.end(),ongoing_vulnerable_list, it);
if ( emitted_vulnerable_list.size() > 100000 ){
}
}
return;
}
}
cout<<"\tError: can't find the following ongoing vulnerable_time object"<<endl;
exit(0);
}
// Some other functions here
};

The list::size() implementation in gcc is of O(n) and in huge lists, calling this function multiple times might be very time consuming.

the problem with list::size() is that you are using list::splice(), and there is no way to track list sizes unless moved items are counted. but it doesn't look that hard to track the sizes manually using two variables.

Related

most efficient way to have a if statement in C++

I am trying to do some Monte Carlo simulation, and as it is with this kind of simulation, it requires a lot of iterations, even for the smallest system. Now I want to do some tweaks with my previous code but it increases the wall time or running time, by 10 fold, which makes a week of calculations to more than two months. I wonder whether I am doing the most efficient way to do the simulation.
Before that, I was using a set of fixed intervals to get the properties of the simulations, but now I want to record a set of random intervals to get the system information as it is the most logical thing to do. However I don't know how to do it.
The code that I was using was basically something like that:
for(long long int it=0; it<numIterations; ++it)
{
if((numIterations>=10) && (it%1000==0))
{
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile1000, it);
}
}
As you see, before the tweaks made it was going through the simulation and only record the data, every 1000th iterations.
Now I want to do something like this
for(long long int it=0; it<numIterations; ++it)
{
for(int j = 1; j <= n_graph_points; ++j){
for (int i = 0; i < n_data_per_graph_points; ++i){
if (it == initial_position_array[j][i] || it == (initial_position_array[j][i] + delta_time_arr[j])) {
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile, it);
}
}
}
}
In this part, the initial position array is just an array with lots of random numbers. The two for loop inside of each other checks every iteration and if the iterations is equal to that random number, it starts recording. I know this is not the best method as it is checking lots of iterations that are not necessary. But, I don't know how can I improve my code. I am a little helpless at this point, so any comment would be appreciated
This does not answer the implied question
[What is the] most efficient way to have [an] if statement in C++ (all of them should be equivalent), but
Supposing varying intervals between exports were logical, how do I code that adequately?
Keep a sane Monte Carlo control, initialise a nextExport variable to a random value to your liking, and whenever it equals nextExport, export and increase nextExport by the next random interval.
if (it == initial_position_array[j][i] || it == (initial_position_array[j][i] + delta_time_arr[j]))
you can use references for both expressions.(please use meaningful names as per your convinience)
int& i_p_a = initial_position_array[j][i];
int& i_p_a_d = (initial_position_array[j][i] + delta_time_arr[j]);
now you final if statement will be readable and maintainable.
if (it == i_p_a || it == i_p_a_d) {
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile, it);
}

Google app script IF condition not matching 0, empty and null

I have issues with Google app script IF condition.
Problem i am facing its not returning value TRUE rather going to next/ Else statements.
Code i am having:
const numberOfRowsToUpdate = deliveryDate.length;
// For each item making the for loop to work
for (i=0 ; i < numberOfRowsToUpdate;i++) {
debugger;
var dp = depositAmount[i];
if(dp!==""|| dp!==0 || dp !==null || dp!==isblank())
{ .... <statements>
}
}
I want to check whether particular cell of the array is empty / zero / returning null value.
thanks in advance for the help.
SUGGESTION
I have used a similar script I'm using for a spreadsheet in which I need to search through every row for some data, but obviously adpating it to your case, and since I don't have your full code (and still can't comment asking for more info due to my recent joining in SO), I had to simplify it, in hope it will work for you.
What I did was use your incrementing i index from the for loop and use it to scan every row, while adjusting it to fit your array index, because we can't have i = 0 as a row index, and it would skip the first value on the array if left as i = 1).
SCRIPT
function test(){
const n = 6;
var depositAmount = [7,2,0,2,0,8];
// For each item making the for loop to work
var ss = SpreadsheetApp.getActive();
Logger.log(ss.getName());
for (var i=1 ; i <= n ;i++) {
debugger;
ss.getRange("A"+i).setValue(1);
var dp = depositAmount[i-1];
Logger.log(dp)
if(dp != "" || dp != 0 /*|| dp != null || dp != isblank()*/)
{
ss.getRange("B"+i).setValue(dp);
}
else
{
ss.getRange("C"+i).setValue("VOID")
Logger.log(i-1+"th index of array is "+ss.getRange("C"+i).getValue());
}
}
};
RESULTS
After running it with the four original conditions you used, i didn't get the expected result, as you must have, leading to this:
.
While studying your original code, I stumbled upon this question about the differences between == and ===, as well as != and !==.
So before I used this in our favor, I tried the old trial and error method, using only one condition at a time, and then stacking them up. Not only I managed to find out the !== operator didn't work properly for this case, but also the comparison with null and the isblank() function (at least in my case, because i haven't defined it, and I'm not sure it is a built-in function) also don't work with either operator.
Therefore, using the != operator helps you better than the strict !==.
The result of the final script is that:
.
NOTES
I also tried using a null value within the array ([7,2,0,2,,8]), but it would always break away from the loop, never scanning the whole array, and I don't know how to circle that.
Here is the Execution Log for this script:
EDIT
While fooling around, I found this question and the answer by Etienne de Villers might be even faster to apply, or at least more useful for your purposes.

How to infinite loop or loop up to a limit without an if-else

I'm wondering if there's a way to write a function that takes one input, a max count for the number of times to loop, that will do an infinite loop if the number is negative, without using an if-else
i.e.
void func(int nAttempts) // if nAttempts <= 0, do an infinite loop
{
if ( nAttempts <= 0 )
{ // do an infinite loop
}
else
{ // do a loop up to nAttemtps
}
}
I'd like to know if there's a way to do that without an if-else
while ((nAttempts < 0) || (nAttempts-- > 0)) {...}
but... why? This makes your code less readable, where an if/else makes it pretty clear what your intentions are.
I take it this is some sort of a trick question? Here's my take:
void f(int n)
{
n < 0 ? []{ while(true); }() : [&]{ while(n--); }() ;
}
The loop itself has a conditional inside of it, it is not an explicit if, but it is a branch. The actual evaluation of that expression is turing complete as well due to lazy evaluation. As a result, this question is kind of nonsensical since even without an if statement, there is still a conditional statement taking place. However, the answer to your question is the following:
void optionalInfiniteLoop(int nAttempts){
while(nAttempts < 0 || nAttempts-- != 0){
...
}
}
Looking at this and understanding lazy evaluation, nAttempts < 0 is evaluated first. If it is true, the || does not need to run, and so it will never wrap the int around by subtracting too far. If it is false, then the second part of the while loop evaluates until nAttempts becomes 0. I don't think you'd save anything by doing this, and indeed, you may be forcing the computer to do slightly more work every iteration by checking nAttempts < 0 instead of just doing that once.
The performance is almost definitely not going to be measurable in the context of an application, and I think the above looks cleaner, but it's really more of a stylistic approach than a technical one.
void func( int nAttempts )
{
while (nAttempts)
{
// do stuff
--nAttempts;
}
}
Basically at the end of every iteration, you subtract one 'try'. When it hits 0 you stop. If it was already negative to begin with, it will become increasingly negative (though I suppose eventually it would overflow).

Best practice for having two if statements from the same bool c++

I have an if statement that [obviously] only runs if the condition is true. After this if statement there is some code that should always run, after that is another if statement that should run under the same condition as the first.
The code in the middle is performing an operation using a particular element of a stack, the ifs on either side perform a push/pop on the stack before and after the operation respectively.
so the logic is something like this:
Do I need to push the stack? yes/no
perform operation on top of stack
Was the stack pushed? (if yes then pop)
items 1 and 3 are the same condition.
This is the code that I first wrote to do this in c++
#include <stdio.h>
#include <stdlib.h>
int somefunction(){
return rand() % 3 + 1; //return a random number from 1 to 3
}
int ret = 0;
//:::::::::::::::::::::::::::::::::::::::
// Option 1 Start
//:::::::::::::::::::::::::::::::::::::::
int main(){
bool run = (ret = somefunction()) == 1; //if the return of the function is 1
run = (run || (ret == 2)); //or the return of the function is 2
if (run){ //execute this if block
//conditional code
if (ret == 1){
//more conditional code
}
}
//unconditional code
if (run){
//even more conditional code
}
}
//:::::::::::::::::::::::::::::::::::::::
// Option 1 End
//:::::::::::::::::::::::::::::::::::::::
After writing this I thought that it might be more efficient to do this:
//:::::::::::::::::::::::::::::::::::::::
// Option 2 Start
//:::::::::::::::::::::::::::::::::::::::
int main(){
bool run;
if (run=(((ret = somefunction()) == 1)||ret == 2)){ //if the return of the function is 1 or 2 then execute this if block
//conditional code
if (ret == 1){
//more conditional code
}
}
//unconditional code
if (run){
//even more conditional code
}
}
//:::::::::::::::::::::::::::::::::::::::
// Option 2 End
//:::::::::::::::::::::::::::::::::::::::
I prefer the first method for readability as it is split into several lines whereas the second has two assignments (=) and two comparisons (==) in the same line.
I want to know if it is better to use the second method (for reasons of efficiency or executable size) or if there is a better method than both.
Before anyone says it will only make an almost immeasurable difference, this is in a huge loop that has to run many thousands of times within 1/50 of a second so I would like to save as much time as possible.
Performance should not be your concern: the modern compilers are usually smart enough to optimize the code in any case. The results will be the same if the code is doing essentially the same thing.
So you should prefer the variant which is more readable (and therefore better maintainable).
I would write something like that:
ret = somefunction();
// I don't know what is the semantics of ret == 1, so let's imagine some
bool operationIsPush = (ret == 1);
bool operationIsOnTop = (ret == 2);
if (operationIsPush || operationIsOnTop)
{
//conditional code
}
if (operationIsPush)
{
//more conditional code
}
//unconditional code
if (operationIsPush || operationIsOnTop)
{
// ...
}
I believe there will be no difference in the performance here. The first reason is that your compiler will probably optimize the code in each case. The second is that you just change the place where operations take place (like "I do A->B->C or A->C->B"), not the amount of operations, so it's always the same amount of computing (1 function call, a couple of == and so on).
However consider that this
(run=(((ret = somefunction()) == 1)||ret == 2))
is pretty hard to read.
Correctness is more important than whether you fold two operations assigning a bool into one (which the compiler will probably do anyway).
For pushing/popping a stack, you should use a scopeguard (original article here). This will ensure that if something throws in the "unconditional bit", which you never really know for sure, then it still runs correctly. Otherwise you get funny a surprise (stack off by one, or overflowing).
if theres a situation that you can split "if-else" to distinct huge loops, it will be faster
rather than
loop { if_1 {some work} if_2 {some other work} }
you can
if_1 { loop {work }} if_2 {loop{same work}}
even more extremely, if you can split the most inner "if" sentences, you can have 10-20(dpending on your situation) distinct huge loops that runs x2 x3 faster (if it is slow bacause of "if")

A* pathfinding slow

I am currently working on a A* search algorithm. The algorithm would just be solving text file mazes. I know that the A* algorithm is supposed to be very quick in finding the finish. Mine seems to take 6 seconds to find the path in a 20x20 maze with no walls. It does find the finish with the correct path it just takes forever to do so.
If I knew which part of code was the problem I would just post that but I really have no idea what is going wrong. So here is the algorithm that I use...
while(!openList.empty()) {
visitedList.push_back(openList[index]);
openList.erase(openList.begin() + index);
if(currentCell->x_coor == goalCell->x_coor && currentCell->y_coor == goalCell->y_coor)
}
FindBestPath(currentCell);
break;
}
if(map[currentCell->x_coor+1][currentCell->y_coor] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor+1,currentCell->y_coor,currentCell));
}
if(map[currentCell->x_coor-1][currentCell->y_coor] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor-1,currentCell->y_coor,currentCell));
}
if(map[currentCell->x_coor][currentCell->y_coor+1] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor,currentCell->y_coor+1,currentCell));
}
if(map[currentCell->x_coor][currentCell->y_coor-1] != wall)
{
openList.push_back(new SearchCell(currentCell->x_coor,currentCell->y_coor-1,currentCell));
}
for(int i=0;i<openList.size();i++) {
openList[i]->G = openList[i]->parent->G + 1;
openList[i]->H = openList[i]->ManHattenDistance(goalCell);
}
float bestF = 999999;
index = -1;
for(int i=0;i<openList.size();i++) {
if(openList[i]->GetF() < bestF) {
for(int n=0;n<visitedList.size();n++) {
if(CheckVisited(openList[i])) {
bestF = openList[i]->GetF();
index = i;
}
}
}
}
if(index >= 0) {
currentCell = openList[index];
}
}
I know this code is messy and not the most efficient way to do things but I think it should still be faster then what it is. Any help would be greatly appreciated.
Thanks.
Your 20x20 maze has no walls, and therefore many, many routes which are all the same length. I'd estimate trillions of equivalent routes, in fact. It doesn't seem so bad when you take that into account.
Of course, since your heuristic looks perfect, you should get a big benefit from excluding routes that are heuristically predicted to be precisely as long as the best route known so far. (This is safe if your heuristic is correct, i.e. never overestimates the remaining distance).
Here is a big hint.
If ever you find two paths to the same cell, you can always throw away the longer one. If there is a tie, you can throw away the second one to get there.
If you implement that, with no other optimizations, the search would become more than acceptably fast.
Secondly the A* algorithm should only bother backtracking if the length to the current cell plus the heuristic exceeds the length to the current cell plus the heuristic for any other node. If you implement that, then it should directly find a path and stop. To facilitate that you need to store paths in a priority queue (typically implemented with a heap), not a vector.
openList.erase is O(n), and the for-loop beginning with for(int i=0;i<openList.size();i++) is O(n^2) due to the call to CheckVisited - these are called every iteration, making your overall algorithm O(n^3). A* should be O(n log n).
Try changing openList to a priority-queue like it's supposed to be, and visitedList to a hash table. The entire for loop can then be replaced by a dequeue - make sure you check if visitedList.Contains(node) before enqueuing!
Also, there is no need to recalculate the ManHattenDistance for every node every iteration, since it never changes.
Aren't you constantly backtracking?
The A* algorithm backtracks when the current best solution becomes worse than another previously visited route. In your case, since there are no walls, all routes are good and never die (and as MSalters correctly pointed, there are several of them). When you take a step, your route becomes worse than all the others that are one step shorter.
If that is true, this may account for the time taken by your algorithm.