Shortest Job First Preemptive
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
0
down vote
favorite
I will write code for all scheduling algorithm in future that is why scheduling.h will contain common data members and member functions. Please help me to improve and optimise this code.
scheduling.h
#ifndef SCHEDULING_H_
#define SCHEDULING_H_
#include <vector>
typedef unsigned int uint;
class Scheduling
uint currActiveProcessID;
uint timeCounter = 0;
std::vector<uint> arrivalTime;
//When process start to execute
std::vector<uint> burstTime;
//process wait to execute after they have arrived
std::vector<uint> waitingTime;
public:
Scheduling(uint);
Scheduling() = default;
Scheduling(const Scheduling&) = delete;
Scheduling &operator=(const Scheduling&) = delete;
Scheduling(Scheduling&&) = delete;
Scheduling &operator=(Scheduling&&) = delete;
~Scheduling() = default;
void calcWaitingTime();
void printInfo();
;
#endif
sjf_preemptive.cpp
#include <iostream>
#include <array>
#include <vector>
#include <algorithm> // std::find
#include <iterator> // std::begin, std::end
#include <limits> //std::numeric_limits
#include "scheduling.h"
typedef unsigned int uint;
Scheduling::Scheduling(uint n)
for ( int i = 0; i < n; i++)
arrivalTime.reserve(n);
burstTime.reserve(n);
waitingTime.reserve(n);
uint val;
std::cout << "Enter arrival time for process " << i+1 << "n";
std::cin >> val;
arrivalTime.push_back(val);
std::cout << "Enter burst time for process " << i+1 << "n";
std::cin >> val;
burstTime.push_back(val);
waitingTime.push_back(0);
bool isAllZeroes(std::vector<uint>& burstTimeCopy)
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0)
return false;
else
return true;
void Scheduling::calcWaitingTime()
std::vector<uint> burstTimeCopy;
burstTimeCopy.reserve(burstTime.size());
uint index = 0;
std::vector<uint>::iterator it;
while (isAllZeroes(burstTimeCopy) == false)
auto max = std::max_element(arrivalTime.begin(), arrivalTime.end());
if (timeCounter <= *max)
else
uint minBurstTime = std::numeric_limits<uint>::max();
//Find index with minimum burst Time remaining
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0 && burstTimeCopy[i] < minBurstTime)
minBurstTime = burstTimeCopy[i];
index = i;
currActiveProcessID = index;
burstTimeCopy[index] -= minBurstTime;
for (int i = 0; i < arrivalTime.size(); i++)
if (i != currActiveProcessID && burstTimeCopy[i] != 0)
waitingTime[i] = waitingTime[i] + minBurstTime;
timeCounter += minBurstTime;
void Scheduling::printInfo()
std::cout << "ProcessIDtArrival TimetBurst TimetWaiting Timen";
for (int i = 0; i < arrivalTime.size(); i++)
std::cout << i+1 << "tt" << arrivalTime[i] << "tt" << burstTime[i];
std::cout << "tt" << waitingTime[i] << "n";
int main()
int num;
std::cout << "Enter the number of processesn";
std::cin >> num;
Scheduling shortestJobFirst(num);
shortestJobFirst.calcWaitingTime();
shortestJobFirst.printInfo();
c++ c++11
add a comment |Â
up vote
0
down vote
favorite
I will write code for all scheduling algorithm in future that is why scheduling.h will contain common data members and member functions. Please help me to improve and optimise this code.
scheduling.h
#ifndef SCHEDULING_H_
#define SCHEDULING_H_
#include <vector>
typedef unsigned int uint;
class Scheduling
uint currActiveProcessID;
uint timeCounter = 0;
std::vector<uint> arrivalTime;
//When process start to execute
std::vector<uint> burstTime;
//process wait to execute after they have arrived
std::vector<uint> waitingTime;
public:
Scheduling(uint);
Scheduling() = default;
Scheduling(const Scheduling&) = delete;
Scheduling &operator=(const Scheduling&) = delete;
Scheduling(Scheduling&&) = delete;
Scheduling &operator=(Scheduling&&) = delete;
~Scheduling() = default;
void calcWaitingTime();
void printInfo();
;
#endif
sjf_preemptive.cpp
#include <iostream>
#include <array>
#include <vector>
#include <algorithm> // std::find
#include <iterator> // std::begin, std::end
#include <limits> //std::numeric_limits
#include "scheduling.h"
typedef unsigned int uint;
Scheduling::Scheduling(uint n)
for ( int i = 0; i < n; i++)
arrivalTime.reserve(n);
burstTime.reserve(n);
waitingTime.reserve(n);
uint val;
std::cout << "Enter arrival time for process " << i+1 << "n";
std::cin >> val;
arrivalTime.push_back(val);
std::cout << "Enter burst time for process " << i+1 << "n";
std::cin >> val;
burstTime.push_back(val);
waitingTime.push_back(0);
bool isAllZeroes(std::vector<uint>& burstTimeCopy)
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0)
return false;
else
return true;
void Scheduling::calcWaitingTime()
std::vector<uint> burstTimeCopy;
burstTimeCopy.reserve(burstTime.size());
uint index = 0;
std::vector<uint>::iterator it;
while (isAllZeroes(burstTimeCopy) == false)
auto max = std::max_element(arrivalTime.begin(), arrivalTime.end());
if (timeCounter <= *max)
else
uint minBurstTime = std::numeric_limits<uint>::max();
//Find index with minimum burst Time remaining
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0 && burstTimeCopy[i] < minBurstTime)
minBurstTime = burstTimeCopy[i];
index = i;
currActiveProcessID = index;
burstTimeCopy[index] -= minBurstTime;
for (int i = 0; i < arrivalTime.size(); i++)
if (i != currActiveProcessID && burstTimeCopy[i] != 0)
waitingTime[i] = waitingTime[i] + minBurstTime;
timeCounter += minBurstTime;
void Scheduling::printInfo()
std::cout << "ProcessIDtArrival TimetBurst TimetWaiting Timen";
for (int i = 0; i < arrivalTime.size(); i++)
std::cout << i+1 << "tt" << arrivalTime[i] << "tt" << burstTime[i];
std::cout << "tt" << waitingTime[i] << "n";
int main()
int num;
std::cout << "Enter the number of processesn";
std::cin >> num;
Scheduling shortestJobFirst(num);
shortestJobFirst.calcWaitingTime();
shortestJobFirst.printInfo();
c++ c++11
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I will write code for all scheduling algorithm in future that is why scheduling.h will contain common data members and member functions. Please help me to improve and optimise this code.
scheduling.h
#ifndef SCHEDULING_H_
#define SCHEDULING_H_
#include <vector>
typedef unsigned int uint;
class Scheduling
uint currActiveProcessID;
uint timeCounter = 0;
std::vector<uint> arrivalTime;
//When process start to execute
std::vector<uint> burstTime;
//process wait to execute after they have arrived
std::vector<uint> waitingTime;
public:
Scheduling(uint);
Scheduling() = default;
Scheduling(const Scheduling&) = delete;
Scheduling &operator=(const Scheduling&) = delete;
Scheduling(Scheduling&&) = delete;
Scheduling &operator=(Scheduling&&) = delete;
~Scheduling() = default;
void calcWaitingTime();
void printInfo();
;
#endif
sjf_preemptive.cpp
#include <iostream>
#include <array>
#include <vector>
#include <algorithm> // std::find
#include <iterator> // std::begin, std::end
#include <limits> //std::numeric_limits
#include "scheduling.h"
typedef unsigned int uint;
Scheduling::Scheduling(uint n)
for ( int i = 0; i < n; i++)
arrivalTime.reserve(n);
burstTime.reserve(n);
waitingTime.reserve(n);
uint val;
std::cout << "Enter arrival time for process " << i+1 << "n";
std::cin >> val;
arrivalTime.push_back(val);
std::cout << "Enter burst time for process " << i+1 << "n";
std::cin >> val;
burstTime.push_back(val);
waitingTime.push_back(0);
bool isAllZeroes(std::vector<uint>& burstTimeCopy)
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0)
return false;
else
return true;
void Scheduling::calcWaitingTime()
std::vector<uint> burstTimeCopy;
burstTimeCopy.reserve(burstTime.size());
uint index = 0;
std::vector<uint>::iterator it;
while (isAllZeroes(burstTimeCopy) == false)
auto max = std::max_element(arrivalTime.begin(), arrivalTime.end());
if (timeCounter <= *max)
else
uint minBurstTime = std::numeric_limits<uint>::max();
//Find index with minimum burst Time remaining
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0 && burstTimeCopy[i] < minBurstTime)
minBurstTime = burstTimeCopy[i];
index = i;
currActiveProcessID = index;
burstTimeCopy[index] -= minBurstTime;
for (int i = 0; i < arrivalTime.size(); i++)
if (i != currActiveProcessID && burstTimeCopy[i] != 0)
waitingTime[i] = waitingTime[i] + minBurstTime;
timeCounter += minBurstTime;
void Scheduling::printInfo()
std::cout << "ProcessIDtArrival TimetBurst TimetWaiting Timen";
for (int i = 0; i < arrivalTime.size(); i++)
std::cout << i+1 << "tt" << arrivalTime[i] << "tt" << burstTime[i];
std::cout << "tt" << waitingTime[i] << "n";
int main()
int num;
std::cout << "Enter the number of processesn";
std::cin >> num;
Scheduling shortestJobFirst(num);
shortestJobFirst.calcWaitingTime();
shortestJobFirst.printInfo();
c++ c++11
I will write code for all scheduling algorithm in future that is why scheduling.h will contain common data members and member functions. Please help me to improve and optimise this code.
scheduling.h
#ifndef SCHEDULING_H_
#define SCHEDULING_H_
#include <vector>
typedef unsigned int uint;
class Scheduling
uint currActiveProcessID;
uint timeCounter = 0;
std::vector<uint> arrivalTime;
//When process start to execute
std::vector<uint> burstTime;
//process wait to execute after they have arrived
std::vector<uint> waitingTime;
public:
Scheduling(uint);
Scheduling() = default;
Scheduling(const Scheduling&) = delete;
Scheduling &operator=(const Scheduling&) = delete;
Scheduling(Scheduling&&) = delete;
Scheduling &operator=(Scheduling&&) = delete;
~Scheduling() = default;
void calcWaitingTime();
void printInfo();
;
#endif
sjf_preemptive.cpp
#include <iostream>
#include <array>
#include <vector>
#include <algorithm> // std::find
#include <iterator> // std::begin, std::end
#include <limits> //std::numeric_limits
#include "scheduling.h"
typedef unsigned int uint;
Scheduling::Scheduling(uint n)
for ( int i = 0; i < n; i++)
arrivalTime.reserve(n);
burstTime.reserve(n);
waitingTime.reserve(n);
uint val;
std::cout << "Enter arrival time for process " << i+1 << "n";
std::cin >> val;
arrivalTime.push_back(val);
std::cout << "Enter burst time for process " << i+1 << "n";
std::cin >> val;
burstTime.push_back(val);
waitingTime.push_back(0);
bool isAllZeroes(std::vector<uint>& burstTimeCopy)
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0)
return false;
else
return true;
void Scheduling::calcWaitingTime()
std::vector<uint> burstTimeCopy;
burstTimeCopy.reserve(burstTime.size());
uint index = 0;
std::vector<uint>::iterator it;
while (isAllZeroes(burstTimeCopy) == false)
auto max = std::max_element(arrivalTime.begin(), arrivalTime.end());
if (timeCounter <= *max)
else
uint minBurstTime = std::numeric_limits<uint>::max();
//Find index with minimum burst Time remaining
for (int i = 0; i < burstTimeCopy.size(); i++)
if (burstTimeCopy[i] != 0 && burstTimeCopy[i] < minBurstTime)
minBurstTime = burstTimeCopy[i];
index = i;
currActiveProcessID = index;
burstTimeCopy[index] -= minBurstTime;
for (int i = 0; i < arrivalTime.size(); i++)
if (i != currActiveProcessID && burstTimeCopy[i] != 0)
waitingTime[i] = waitingTime[i] + minBurstTime;
timeCounter += minBurstTime;
void Scheduling::printInfo()
std::cout << "ProcessIDtArrival TimetBurst TimetWaiting Timen";
for (int i = 0; i < arrivalTime.size(); i++)
std::cout << i+1 << "tt" << arrivalTime[i] << "tt" << burstTime[i];
std::cout << "tt" << waitingTime[i] << "n";
int main()
int num;
std::cout << "Enter the number of processesn";
std::cin >> num;
Scheduling shortestJobFirst(num);
shortestJobFirst.calcWaitingTime();
shortestJobFirst.printInfo();
c++ c++11
edited Jun 24 at 17:00
Jamalâ¦
30.1k11114225
30.1k11114225
asked Jun 22 at 17:59
coder
911425
911425
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
Some things to consider:
- You've tagged your question with c++11, implying that you're using that version of the C++ language to compile your code. As such, you should shun the use of
typedef
as much as possible, since in C++11, the much more flexible and much more readableusing
was introduced. Applied to your code,typedef unsigned int uint
would becomeusing uint = unsigned int
, for example. - Speaking of type aliases: Please put your code into an appropriate namespace. Especially since you just straight up typedef the extremely common name
uint
, the probability of causing some sort of incompatibility with other libraries is extremely high. Speaking of that, do you really need theuint
typedef? Usually, you should strive to keep your headers as clean as possible, and that typedef strikes me as neither aimed at users of your library nor as helpful in any other way. - Instead of offering both a default constructor and a constructor taking a single
uint
, consider removing the default constructor and adding a default argument value of 0 to theuint
-constructor, since calling that constructor with argument 0 does basically the same as default constructing. - In
for
-loops, such as infor ( int i = 0; i < n; i++)
, don't useint
unless you're sure it's appropriate. In this case,n
is of typeunsigned int
, so as a user I could theoretically passstd::numeric_limits<unsigned int>::max()
, in which case your code would have undefined behavior. - You're reserving
n
entries of memory for your three vectors in each iteration of thefor
-loop inScheduling(uint n)
, i.e. n^2 entries in general. This is bad, because 1)reserve
is not a cheap operation, 2) you're running a serious risk of your program dieing from out of memory for largen
and 3) you don't need that much memory at all. Instead of reserving every iteration, reserven
elements up front, then iterate. - Related to the above point, while you are filling
arrivalTime
andburstTime
with data from standard input,waitingTime
is only filled with 0s. Luckily,std::vector
comes with a constructor that exist exactly for this purpose (= creating a vector withn
copies of an element). I recommend you instead put the initialization ofwaitingTime
into the member initialization list, like so:Scheduling::Scheduling(uint n) : waitingTime(n, 0) { ...
. - There are a lot of things wrong with
isAllZeroes
:- First of all, this function should be
static
, since it is not exported via your header and thus only used locally. - Secondly, the function is bugged and does not work. You're not actually checking whether all elements are 0; instead, you're just checking the first element and return whether that's 0 or not.
- Third, you're taking one argument, named
burstTimeCopy
, via non-const reference. However, you're not doing any modifications to it; so that should be a const reference. Also, there's no actual copying involved, so the variable name is misleading. - Fourth, that
for
-loop has the same issue I already mentioned in point 4 above. Sincestd::vector::size()
returns a result of typestd::size_t
, you should make your iteration variable of that type as well, or risk undefined behavior via overflow. However, you actually don't need to manually write out thatfor
-loop at all, since there exists a for-each construct since C++11:for (uint element : bustTimeCopy)
does the same, but is much more concise and doesn't introduce another clutter variable. - Actually, this whole function can be replaced by a single call to
std::all_of
from thealgorithm
header. You could just writereturn std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(), (uint e) return e == 0; );
for the function body and be done, or even drop the function all together and replace its invocations by this one liner.
- First of all, this function should be
- Don't compare boolean results for equality. By this I mean that writing
if (some_bool_thing == true)
orif (some_bool_thing == false)
can and should be replaced byif (some_bool_thing)
andif (!some_bool_thing)
, respectively. Otherwise, you're just being unnecessarily verbose. calcWaitingTime
is somewhat messy right now. The method spans a whopping 70 lines, and consists of a lot of nestedif
s,for
s andwhile
s. As of right now, the method is barely readable, and probably even harder to maintain.What can be done about that? First of all, one of the most important principles for writing good and maintainable code is to granularize, i.e. to split up everything into small, digestible pieces that are easier to verify and easier to work with than giant, monolithic constructs. As a rule of thumb, almost all functions should consist of no more than a handful of individual statements, where a handful varies a bit by whom you ask, but is generally somewhere below 20, or even below 10.
Coming back to the example at hand, I recommend you to go through the method, and every time you see a new
if
, or afor
or awhile
, take some time and think whether these could be succinctly expressed as their own functions. If you think they can be, go ahead and write that function, and replace the existing structure with that. Then, go through the code once more and look for similarities in the functions you just extracted. If you find that two functions are similar enough, try merging them into a single function.Another thing I recommend you is taking some time and getting familiar with the functionality offered in the algorithm library, of which you have already made use a little. These algorithms encode extremely common patterns, such as checking whether all things in a container satisfy certain criteria, or finding elements, or summing all elements, etc. Then, go through you code again and try to look for common patterns which can be easily expressed through these algorithms. For example, there's a comment saying
//Find index with minimum burst Time remaining
in there, which suggests that the following code might be easily replaceable by a call tostd::find
or one of its friends.I am not going to go into the gory details of
calcWaitingTime
here and analyze it, because I find the method as it currently is extremely hard to parse and understand, and I don't want to invest the time necessary to get a good overview. If you're interested in a more in-depth review of that method, please do some clean-up and post a follow up question, or hope that somebody has more patience than I do and will go through the whole 70 lines.- When printing out single characters, such as
n
, use single quotes instead of double quotes, i.e.std::cout << 'n'
overstd::cout << "n"
. The latter entails a pointer dereference and a call tostd::strlen
, which are both wasted performance. (The performance loss is probably negligible in most cases, but the change is so small and simple that it's still worth doing, in my opinion.)
Some of the above criticism is pretty harsh, I admit. Still, I hope that you're not taking it too personally, because my goal is not to denigrate or attack you, just to point out what's not good about your code and how to improve it. Admittedly, I'm not know to sugarcoat things, so please tell me if you feel that my criticism is unjust, or wrong, or in any other way not fair. Also, while this should go without saying, please feel free to ask if there's anything unclear.
add a comment |Â
up vote
0
down vote
Code looks clean overall and quite easy to digest. But there are some issues.
1) isAllZeroes() is not correctly implemented.
2) You make a copy of the burstTime vector but the original doesn't seem to be updated. Why a copy then?
3) The copy is not actually done, only the allocation.
Note that I don't have full knowledge of the algorithm you implemented here.
I have made copy because I don't want to modify originalburstTime
and functioncalcWaitingTime()
modifiesburstTimeCopy
.
â coder
Jun 22 at 18:35
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Some things to consider:
- You've tagged your question with c++11, implying that you're using that version of the C++ language to compile your code. As such, you should shun the use of
typedef
as much as possible, since in C++11, the much more flexible and much more readableusing
was introduced. Applied to your code,typedef unsigned int uint
would becomeusing uint = unsigned int
, for example. - Speaking of type aliases: Please put your code into an appropriate namespace. Especially since you just straight up typedef the extremely common name
uint
, the probability of causing some sort of incompatibility with other libraries is extremely high. Speaking of that, do you really need theuint
typedef? Usually, you should strive to keep your headers as clean as possible, and that typedef strikes me as neither aimed at users of your library nor as helpful in any other way. - Instead of offering both a default constructor and a constructor taking a single
uint
, consider removing the default constructor and adding a default argument value of 0 to theuint
-constructor, since calling that constructor with argument 0 does basically the same as default constructing. - In
for
-loops, such as infor ( int i = 0; i < n; i++)
, don't useint
unless you're sure it's appropriate. In this case,n
is of typeunsigned int
, so as a user I could theoretically passstd::numeric_limits<unsigned int>::max()
, in which case your code would have undefined behavior. - You're reserving
n
entries of memory for your three vectors in each iteration of thefor
-loop inScheduling(uint n)
, i.e. n^2 entries in general. This is bad, because 1)reserve
is not a cheap operation, 2) you're running a serious risk of your program dieing from out of memory for largen
and 3) you don't need that much memory at all. Instead of reserving every iteration, reserven
elements up front, then iterate. - Related to the above point, while you are filling
arrivalTime
andburstTime
with data from standard input,waitingTime
is only filled with 0s. Luckily,std::vector
comes with a constructor that exist exactly for this purpose (= creating a vector withn
copies of an element). I recommend you instead put the initialization ofwaitingTime
into the member initialization list, like so:Scheduling::Scheduling(uint n) : waitingTime(n, 0) { ...
. - There are a lot of things wrong with
isAllZeroes
:- First of all, this function should be
static
, since it is not exported via your header and thus only used locally. - Secondly, the function is bugged and does not work. You're not actually checking whether all elements are 0; instead, you're just checking the first element and return whether that's 0 or not.
- Third, you're taking one argument, named
burstTimeCopy
, via non-const reference. However, you're not doing any modifications to it; so that should be a const reference. Also, there's no actual copying involved, so the variable name is misleading. - Fourth, that
for
-loop has the same issue I already mentioned in point 4 above. Sincestd::vector::size()
returns a result of typestd::size_t
, you should make your iteration variable of that type as well, or risk undefined behavior via overflow. However, you actually don't need to manually write out thatfor
-loop at all, since there exists a for-each construct since C++11:for (uint element : bustTimeCopy)
does the same, but is much more concise and doesn't introduce another clutter variable. - Actually, this whole function can be replaced by a single call to
std::all_of
from thealgorithm
header. You could just writereturn std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(), (uint e) return e == 0; );
for the function body and be done, or even drop the function all together and replace its invocations by this one liner.
- First of all, this function should be
- Don't compare boolean results for equality. By this I mean that writing
if (some_bool_thing == true)
orif (some_bool_thing == false)
can and should be replaced byif (some_bool_thing)
andif (!some_bool_thing)
, respectively. Otherwise, you're just being unnecessarily verbose. calcWaitingTime
is somewhat messy right now. The method spans a whopping 70 lines, and consists of a lot of nestedif
s,for
s andwhile
s. As of right now, the method is barely readable, and probably even harder to maintain.What can be done about that? First of all, one of the most important principles for writing good and maintainable code is to granularize, i.e. to split up everything into small, digestible pieces that are easier to verify and easier to work with than giant, monolithic constructs. As a rule of thumb, almost all functions should consist of no more than a handful of individual statements, where a handful varies a bit by whom you ask, but is generally somewhere below 20, or even below 10.
Coming back to the example at hand, I recommend you to go through the method, and every time you see a new
if
, or afor
or awhile
, take some time and think whether these could be succinctly expressed as their own functions. If you think they can be, go ahead and write that function, and replace the existing structure with that. Then, go through the code once more and look for similarities in the functions you just extracted. If you find that two functions are similar enough, try merging them into a single function.Another thing I recommend you is taking some time and getting familiar with the functionality offered in the algorithm library, of which you have already made use a little. These algorithms encode extremely common patterns, such as checking whether all things in a container satisfy certain criteria, or finding elements, or summing all elements, etc. Then, go through you code again and try to look for common patterns which can be easily expressed through these algorithms. For example, there's a comment saying
//Find index with minimum burst Time remaining
in there, which suggests that the following code might be easily replaceable by a call tostd::find
or one of its friends.I am not going to go into the gory details of
calcWaitingTime
here and analyze it, because I find the method as it currently is extremely hard to parse and understand, and I don't want to invest the time necessary to get a good overview. If you're interested in a more in-depth review of that method, please do some clean-up and post a follow up question, or hope that somebody has more patience than I do and will go through the whole 70 lines.- When printing out single characters, such as
n
, use single quotes instead of double quotes, i.e.std::cout << 'n'
overstd::cout << "n"
. The latter entails a pointer dereference and a call tostd::strlen
, which are both wasted performance. (The performance loss is probably negligible in most cases, but the change is so small and simple that it's still worth doing, in my opinion.)
Some of the above criticism is pretty harsh, I admit. Still, I hope that you're not taking it too personally, because my goal is not to denigrate or attack you, just to point out what's not good about your code and how to improve it. Admittedly, I'm not know to sugarcoat things, so please tell me if you feel that my criticism is unjust, or wrong, or in any other way not fair. Also, while this should go without saying, please feel free to ask if there's anything unclear.
add a comment |Â
up vote
2
down vote
accepted
Some things to consider:
- You've tagged your question with c++11, implying that you're using that version of the C++ language to compile your code. As such, you should shun the use of
typedef
as much as possible, since in C++11, the much more flexible and much more readableusing
was introduced. Applied to your code,typedef unsigned int uint
would becomeusing uint = unsigned int
, for example. - Speaking of type aliases: Please put your code into an appropriate namespace. Especially since you just straight up typedef the extremely common name
uint
, the probability of causing some sort of incompatibility with other libraries is extremely high. Speaking of that, do you really need theuint
typedef? Usually, you should strive to keep your headers as clean as possible, and that typedef strikes me as neither aimed at users of your library nor as helpful in any other way. - Instead of offering both a default constructor and a constructor taking a single
uint
, consider removing the default constructor and adding a default argument value of 0 to theuint
-constructor, since calling that constructor with argument 0 does basically the same as default constructing. - In
for
-loops, such as infor ( int i = 0; i < n; i++)
, don't useint
unless you're sure it's appropriate. In this case,n
is of typeunsigned int
, so as a user I could theoretically passstd::numeric_limits<unsigned int>::max()
, in which case your code would have undefined behavior. - You're reserving
n
entries of memory for your three vectors in each iteration of thefor
-loop inScheduling(uint n)
, i.e. n^2 entries in general. This is bad, because 1)reserve
is not a cheap operation, 2) you're running a serious risk of your program dieing from out of memory for largen
and 3) you don't need that much memory at all. Instead of reserving every iteration, reserven
elements up front, then iterate. - Related to the above point, while you are filling
arrivalTime
andburstTime
with data from standard input,waitingTime
is only filled with 0s. Luckily,std::vector
comes with a constructor that exist exactly for this purpose (= creating a vector withn
copies of an element). I recommend you instead put the initialization ofwaitingTime
into the member initialization list, like so:Scheduling::Scheduling(uint n) : waitingTime(n, 0) { ...
. - There are a lot of things wrong with
isAllZeroes
:- First of all, this function should be
static
, since it is not exported via your header and thus only used locally. - Secondly, the function is bugged and does not work. You're not actually checking whether all elements are 0; instead, you're just checking the first element and return whether that's 0 or not.
- Third, you're taking one argument, named
burstTimeCopy
, via non-const reference. However, you're not doing any modifications to it; so that should be a const reference. Also, there's no actual copying involved, so the variable name is misleading. - Fourth, that
for
-loop has the same issue I already mentioned in point 4 above. Sincestd::vector::size()
returns a result of typestd::size_t
, you should make your iteration variable of that type as well, or risk undefined behavior via overflow. However, you actually don't need to manually write out thatfor
-loop at all, since there exists a for-each construct since C++11:for (uint element : bustTimeCopy)
does the same, but is much more concise and doesn't introduce another clutter variable. - Actually, this whole function can be replaced by a single call to
std::all_of
from thealgorithm
header. You could just writereturn std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(), (uint e) return e == 0; );
for the function body and be done, or even drop the function all together and replace its invocations by this one liner.
- First of all, this function should be
- Don't compare boolean results for equality. By this I mean that writing
if (some_bool_thing == true)
orif (some_bool_thing == false)
can and should be replaced byif (some_bool_thing)
andif (!some_bool_thing)
, respectively. Otherwise, you're just being unnecessarily verbose. calcWaitingTime
is somewhat messy right now. The method spans a whopping 70 lines, and consists of a lot of nestedif
s,for
s andwhile
s. As of right now, the method is barely readable, and probably even harder to maintain.What can be done about that? First of all, one of the most important principles for writing good and maintainable code is to granularize, i.e. to split up everything into small, digestible pieces that are easier to verify and easier to work with than giant, monolithic constructs. As a rule of thumb, almost all functions should consist of no more than a handful of individual statements, where a handful varies a bit by whom you ask, but is generally somewhere below 20, or even below 10.
Coming back to the example at hand, I recommend you to go through the method, and every time you see a new
if
, or afor
or awhile
, take some time and think whether these could be succinctly expressed as their own functions. If you think they can be, go ahead and write that function, and replace the existing structure with that. Then, go through the code once more and look for similarities in the functions you just extracted. If you find that two functions are similar enough, try merging them into a single function.Another thing I recommend you is taking some time and getting familiar with the functionality offered in the algorithm library, of which you have already made use a little. These algorithms encode extremely common patterns, such as checking whether all things in a container satisfy certain criteria, or finding elements, or summing all elements, etc. Then, go through you code again and try to look for common patterns which can be easily expressed through these algorithms. For example, there's a comment saying
//Find index with minimum burst Time remaining
in there, which suggests that the following code might be easily replaceable by a call tostd::find
or one of its friends.I am not going to go into the gory details of
calcWaitingTime
here and analyze it, because I find the method as it currently is extremely hard to parse and understand, and I don't want to invest the time necessary to get a good overview. If you're interested in a more in-depth review of that method, please do some clean-up and post a follow up question, or hope that somebody has more patience than I do and will go through the whole 70 lines.- When printing out single characters, such as
n
, use single quotes instead of double quotes, i.e.std::cout << 'n'
overstd::cout << "n"
. The latter entails a pointer dereference and a call tostd::strlen
, which are both wasted performance. (The performance loss is probably negligible in most cases, but the change is so small and simple that it's still worth doing, in my opinion.)
Some of the above criticism is pretty harsh, I admit. Still, I hope that you're not taking it too personally, because my goal is not to denigrate or attack you, just to point out what's not good about your code and how to improve it. Admittedly, I'm not know to sugarcoat things, so please tell me if you feel that my criticism is unjust, or wrong, or in any other way not fair. Also, while this should go without saying, please feel free to ask if there's anything unclear.
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Some things to consider:
- You've tagged your question with c++11, implying that you're using that version of the C++ language to compile your code. As such, you should shun the use of
typedef
as much as possible, since in C++11, the much more flexible and much more readableusing
was introduced. Applied to your code,typedef unsigned int uint
would becomeusing uint = unsigned int
, for example. - Speaking of type aliases: Please put your code into an appropriate namespace. Especially since you just straight up typedef the extremely common name
uint
, the probability of causing some sort of incompatibility with other libraries is extremely high. Speaking of that, do you really need theuint
typedef? Usually, you should strive to keep your headers as clean as possible, and that typedef strikes me as neither aimed at users of your library nor as helpful in any other way. - Instead of offering both a default constructor and a constructor taking a single
uint
, consider removing the default constructor and adding a default argument value of 0 to theuint
-constructor, since calling that constructor with argument 0 does basically the same as default constructing. - In
for
-loops, such as infor ( int i = 0; i < n; i++)
, don't useint
unless you're sure it's appropriate. In this case,n
is of typeunsigned int
, so as a user I could theoretically passstd::numeric_limits<unsigned int>::max()
, in which case your code would have undefined behavior. - You're reserving
n
entries of memory for your three vectors in each iteration of thefor
-loop inScheduling(uint n)
, i.e. n^2 entries in general. This is bad, because 1)reserve
is not a cheap operation, 2) you're running a serious risk of your program dieing from out of memory for largen
and 3) you don't need that much memory at all. Instead of reserving every iteration, reserven
elements up front, then iterate. - Related to the above point, while you are filling
arrivalTime
andburstTime
with data from standard input,waitingTime
is only filled with 0s. Luckily,std::vector
comes with a constructor that exist exactly for this purpose (= creating a vector withn
copies of an element). I recommend you instead put the initialization ofwaitingTime
into the member initialization list, like so:Scheduling::Scheduling(uint n) : waitingTime(n, 0) { ...
. - There are a lot of things wrong with
isAllZeroes
:- First of all, this function should be
static
, since it is not exported via your header and thus only used locally. - Secondly, the function is bugged and does not work. You're not actually checking whether all elements are 0; instead, you're just checking the first element and return whether that's 0 or not.
- Third, you're taking one argument, named
burstTimeCopy
, via non-const reference. However, you're not doing any modifications to it; so that should be a const reference. Also, there's no actual copying involved, so the variable name is misleading. - Fourth, that
for
-loop has the same issue I already mentioned in point 4 above. Sincestd::vector::size()
returns a result of typestd::size_t
, you should make your iteration variable of that type as well, or risk undefined behavior via overflow. However, you actually don't need to manually write out thatfor
-loop at all, since there exists a for-each construct since C++11:for (uint element : bustTimeCopy)
does the same, but is much more concise and doesn't introduce another clutter variable. - Actually, this whole function can be replaced by a single call to
std::all_of
from thealgorithm
header. You could just writereturn std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(), (uint e) return e == 0; );
for the function body and be done, or even drop the function all together and replace its invocations by this one liner.
- First of all, this function should be
- Don't compare boolean results for equality. By this I mean that writing
if (some_bool_thing == true)
orif (some_bool_thing == false)
can and should be replaced byif (some_bool_thing)
andif (!some_bool_thing)
, respectively. Otherwise, you're just being unnecessarily verbose. calcWaitingTime
is somewhat messy right now. The method spans a whopping 70 lines, and consists of a lot of nestedif
s,for
s andwhile
s. As of right now, the method is barely readable, and probably even harder to maintain.What can be done about that? First of all, one of the most important principles for writing good and maintainable code is to granularize, i.e. to split up everything into small, digestible pieces that are easier to verify and easier to work with than giant, monolithic constructs. As a rule of thumb, almost all functions should consist of no more than a handful of individual statements, where a handful varies a bit by whom you ask, but is generally somewhere below 20, or even below 10.
Coming back to the example at hand, I recommend you to go through the method, and every time you see a new
if
, or afor
or awhile
, take some time and think whether these could be succinctly expressed as their own functions. If you think they can be, go ahead and write that function, and replace the existing structure with that. Then, go through the code once more and look for similarities in the functions you just extracted. If you find that two functions are similar enough, try merging them into a single function.Another thing I recommend you is taking some time and getting familiar with the functionality offered in the algorithm library, of which you have already made use a little. These algorithms encode extremely common patterns, such as checking whether all things in a container satisfy certain criteria, or finding elements, or summing all elements, etc. Then, go through you code again and try to look for common patterns which can be easily expressed through these algorithms. For example, there's a comment saying
//Find index with minimum burst Time remaining
in there, which suggests that the following code might be easily replaceable by a call tostd::find
or one of its friends.I am not going to go into the gory details of
calcWaitingTime
here and analyze it, because I find the method as it currently is extremely hard to parse and understand, and I don't want to invest the time necessary to get a good overview. If you're interested in a more in-depth review of that method, please do some clean-up and post a follow up question, or hope that somebody has more patience than I do and will go through the whole 70 lines.- When printing out single characters, such as
n
, use single quotes instead of double quotes, i.e.std::cout << 'n'
overstd::cout << "n"
. The latter entails a pointer dereference and a call tostd::strlen
, which are both wasted performance. (The performance loss is probably negligible in most cases, but the change is so small and simple that it's still worth doing, in my opinion.)
Some of the above criticism is pretty harsh, I admit. Still, I hope that you're not taking it too personally, because my goal is not to denigrate or attack you, just to point out what's not good about your code and how to improve it. Admittedly, I'm not know to sugarcoat things, so please tell me if you feel that my criticism is unjust, or wrong, or in any other way not fair. Also, while this should go without saying, please feel free to ask if there's anything unclear.
Some things to consider:
- You've tagged your question with c++11, implying that you're using that version of the C++ language to compile your code. As such, you should shun the use of
typedef
as much as possible, since in C++11, the much more flexible and much more readableusing
was introduced. Applied to your code,typedef unsigned int uint
would becomeusing uint = unsigned int
, for example. - Speaking of type aliases: Please put your code into an appropriate namespace. Especially since you just straight up typedef the extremely common name
uint
, the probability of causing some sort of incompatibility with other libraries is extremely high. Speaking of that, do you really need theuint
typedef? Usually, you should strive to keep your headers as clean as possible, and that typedef strikes me as neither aimed at users of your library nor as helpful in any other way. - Instead of offering both a default constructor and a constructor taking a single
uint
, consider removing the default constructor and adding a default argument value of 0 to theuint
-constructor, since calling that constructor with argument 0 does basically the same as default constructing. - In
for
-loops, such as infor ( int i = 0; i < n; i++)
, don't useint
unless you're sure it's appropriate. In this case,n
is of typeunsigned int
, so as a user I could theoretically passstd::numeric_limits<unsigned int>::max()
, in which case your code would have undefined behavior. - You're reserving
n
entries of memory for your three vectors in each iteration of thefor
-loop inScheduling(uint n)
, i.e. n^2 entries in general. This is bad, because 1)reserve
is not a cheap operation, 2) you're running a serious risk of your program dieing from out of memory for largen
and 3) you don't need that much memory at all. Instead of reserving every iteration, reserven
elements up front, then iterate. - Related to the above point, while you are filling
arrivalTime
andburstTime
with data from standard input,waitingTime
is only filled with 0s. Luckily,std::vector
comes with a constructor that exist exactly for this purpose (= creating a vector withn
copies of an element). I recommend you instead put the initialization ofwaitingTime
into the member initialization list, like so:Scheduling::Scheduling(uint n) : waitingTime(n, 0) { ...
. - There are a lot of things wrong with
isAllZeroes
:- First of all, this function should be
static
, since it is not exported via your header and thus only used locally. - Secondly, the function is bugged and does not work. You're not actually checking whether all elements are 0; instead, you're just checking the first element and return whether that's 0 or not.
- Third, you're taking one argument, named
burstTimeCopy
, via non-const reference. However, you're not doing any modifications to it; so that should be a const reference. Also, there's no actual copying involved, so the variable name is misleading. - Fourth, that
for
-loop has the same issue I already mentioned in point 4 above. Sincestd::vector::size()
returns a result of typestd::size_t
, you should make your iteration variable of that type as well, or risk undefined behavior via overflow. However, you actually don't need to manually write out thatfor
-loop at all, since there exists a for-each construct since C++11:for (uint element : bustTimeCopy)
does the same, but is much more concise and doesn't introduce another clutter variable. - Actually, this whole function can be replaced by a single call to
std::all_of
from thealgorithm
header. You could just writereturn std::all_of(burstTimeCopy.begin(), burstTimeCopy.end(), (uint e) return e == 0; );
for the function body and be done, or even drop the function all together and replace its invocations by this one liner.
- First of all, this function should be
- Don't compare boolean results for equality. By this I mean that writing
if (some_bool_thing == true)
orif (some_bool_thing == false)
can and should be replaced byif (some_bool_thing)
andif (!some_bool_thing)
, respectively. Otherwise, you're just being unnecessarily verbose. calcWaitingTime
is somewhat messy right now. The method spans a whopping 70 lines, and consists of a lot of nestedif
s,for
s andwhile
s. As of right now, the method is barely readable, and probably even harder to maintain.What can be done about that? First of all, one of the most important principles for writing good and maintainable code is to granularize, i.e. to split up everything into small, digestible pieces that are easier to verify and easier to work with than giant, monolithic constructs. As a rule of thumb, almost all functions should consist of no more than a handful of individual statements, where a handful varies a bit by whom you ask, but is generally somewhere below 20, or even below 10.
Coming back to the example at hand, I recommend you to go through the method, and every time you see a new
if
, or afor
or awhile
, take some time and think whether these could be succinctly expressed as their own functions. If you think they can be, go ahead and write that function, and replace the existing structure with that. Then, go through the code once more and look for similarities in the functions you just extracted. If you find that two functions are similar enough, try merging them into a single function.Another thing I recommend you is taking some time and getting familiar with the functionality offered in the algorithm library, of which you have already made use a little. These algorithms encode extremely common patterns, such as checking whether all things in a container satisfy certain criteria, or finding elements, or summing all elements, etc. Then, go through you code again and try to look for common patterns which can be easily expressed through these algorithms. For example, there's a comment saying
//Find index with minimum burst Time remaining
in there, which suggests that the following code might be easily replaceable by a call tostd::find
or one of its friends.I am not going to go into the gory details of
calcWaitingTime
here and analyze it, because I find the method as it currently is extremely hard to parse and understand, and I don't want to invest the time necessary to get a good overview. If you're interested in a more in-depth review of that method, please do some clean-up and post a follow up question, or hope that somebody has more patience than I do and will go through the whole 70 lines.- When printing out single characters, such as
n
, use single quotes instead of double quotes, i.e.std::cout << 'n'
overstd::cout << "n"
. The latter entails a pointer dereference and a call tostd::strlen
, which are both wasted performance. (The performance loss is probably negligible in most cases, but the change is so small and simple that it's still worth doing, in my opinion.)
Some of the above criticism is pretty harsh, I admit. Still, I hope that you're not taking it too personally, because my goal is not to denigrate or attack you, just to point out what's not good about your code and how to improve it. Admittedly, I'm not know to sugarcoat things, so please tell me if you feel that my criticism is unjust, or wrong, or in any other way not fair. Also, while this should go without saying, please feel free to ask if there's anything unclear.
answered Jun 24 at 19:56
Ben Steffan
4,83511234
4,83511234
add a comment |Â
add a comment |Â
up vote
0
down vote
Code looks clean overall and quite easy to digest. But there are some issues.
1) isAllZeroes() is not correctly implemented.
2) You make a copy of the burstTime vector but the original doesn't seem to be updated. Why a copy then?
3) The copy is not actually done, only the allocation.
Note that I don't have full knowledge of the algorithm you implemented here.
I have made copy because I don't want to modify originalburstTime
and functioncalcWaitingTime()
modifiesburstTimeCopy
.
â coder
Jun 22 at 18:35
add a comment |Â
up vote
0
down vote
Code looks clean overall and quite easy to digest. But there are some issues.
1) isAllZeroes() is not correctly implemented.
2) You make a copy of the burstTime vector but the original doesn't seem to be updated. Why a copy then?
3) The copy is not actually done, only the allocation.
Note that I don't have full knowledge of the algorithm you implemented here.
I have made copy because I don't want to modify originalburstTime
and functioncalcWaitingTime()
modifiesburstTimeCopy
.
â coder
Jun 22 at 18:35
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Code looks clean overall and quite easy to digest. But there are some issues.
1) isAllZeroes() is not correctly implemented.
2) You make a copy of the burstTime vector but the original doesn't seem to be updated. Why a copy then?
3) The copy is not actually done, only the allocation.
Note that I don't have full knowledge of the algorithm you implemented here.
Code looks clean overall and quite easy to digest. But there are some issues.
1) isAllZeroes() is not correctly implemented.
2) You make a copy of the burstTime vector but the original doesn't seem to be updated. Why a copy then?
3) The copy is not actually done, only the allocation.
Note that I don't have full knowledge of the algorithm you implemented here.
edited Jun 22 at 18:30
Daniel
4,1132836
4,1132836
answered Jun 22 at 18:26
rpress
1113
1113
I have made copy because I don't want to modify originalburstTime
and functioncalcWaitingTime()
modifiesburstTimeCopy
.
â coder
Jun 22 at 18:35
add a comment |Â
I have made copy because I don't want to modify originalburstTime
and functioncalcWaitingTime()
modifiesburstTimeCopy
.
â coder
Jun 22 at 18:35
I have made copy because I don't want to modify original
burstTime
and function calcWaitingTime()
modifies burstTimeCopy
.â coder
Jun 22 at 18:35
I have made copy because I don't want to modify original
burstTime
and function calcWaitingTime()
modifies burstTimeCopy
.â coder
Jun 22 at 18:35
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f197076%2fshortest-job-first-preemptive%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password