I have a function that computes the Minimum Spanning Tree of a graph, and I have two different ways to compute the edge weights in the tree.
The edge_weight() function is called inside a few for loops over and over, and which function is used depends on the type of tree, which is specified outside of the main function (by the user).
My problem is that everything inside the for loops besides the edge_weight() function is identical, so I don't want to copy/paste code.
But at the same time I don't want to condition inside the for loops on which edge_weight() function to use, in order to avoid the overhead of a repeated if condition.
So what's the cleanest way to specify which function to use before the for loops start without copy/pasting the same code?
Can I have pointers to functions (does that slow the code down, though?)?
Can I put functions in variables, arrays?
EDIT: Speed is crucial for this application, hence my trying to avoid conditioning inside the for loops.
Here's some pseudo-code:
while(nodes < threshold)
{
for (int i = 0; i < K; i++)
{
if (nodes[i] == something)
{
weight = one_of_two_edge_weight_functions();
Related
In an implementation of the Game of Life, I need to handle user events, perform some regular (as in periodic) processing and draw to a 2D canvas. The details are not particularly important. Suffice it to say that I need to keep track of a large(-ish) number of variables. These are things like: a structure representing the state of the system (live cells), pointers to structures provided by the graphics library, current zoom level, coordinates of the origin and I am sure a few others.
In the main function, there is a game loop like this:
// Setup stuff
while (!finished) {
while (get_event(&e) != 0) {
if (e.type == KEYBOARD_EVENT) {
switch (e.key.keysym) {
case q:
case x:
// More branching and nesting follows
The maximum level of nesting at the moment is 5. It quickly becomes unmanageable and difficult to read, especially on a small screen. The solution then is to split this up into multiple functions. Something like:
while (!finished {
while (get_event(&e) !=0) {
handle_event(state, origin_x, origin_y, &canvas, e...) //More parameters
This is the crux of the question. The subroutine must necessarily have access to the state (represented by the origin, the canvas, the live cells etc.) in order to function. Passing them all explicitly is error prone (which order does the subroutine expect them in) and can also be difficult to read. Aside from that, having functions with potentially 10+ arguments strikes me as a symptom of other design flaws. However the alternatives that I can think of, don't seem any better.
To summarise:
Accept deep nesting in the game loop.
Define functions with very many arguments.
Collate (somewhat) related arguments into structs - This really only hides the problem, especially since the arguments are only loosely related.
Define variables that represent the application state with file scope (static int origin_x; for example). If it weren't for the fact that it has been drummed into me that global variable are usually a terrible idea, this would be my preferred option. But if I want to display two views of the same instance of the Game of Life in the future, then the file scope no longer looks so appealing.
The question also applies in slightly more general terms I suppose: How do you pass state around a complicated program safely and in a readable way?
EDIT:
My motivations here are not speed or efficiency or performance or anything like this. If the code takes 20% longer to run as a result of the choice made here that's just fine. I'm primarily interested in what is less likely to confuse me and cause the least headache in 6 months time.
I would consider the canvas as one variable, containing a large 2D array...
consider static allocation
bool canvas[ROWS][COLS];
or dynamic
bool *canvas = malloc(N*M*sizeof(int));
In both cases you can refer to the cell at position i,j as canvas[i][j]
though for dynamic allocation, do not forget to free(canvas) at the end. You can then use a nested loop to update your state.
Search for allocating/handling a 2d array in C and examples or tutorials... Possibly check something like this or similar? Possibly this? https://www.geeksforgeeks.org/nested-loops-in-c-with-examples/
Also consider this Fastest way to zero out a 2d array in C?
I have my code setup so that I have a movieclip in my library with a class called "block" being duplicated multiple times and added into an array like this:
function makeblock(e:Event){
newblock=new block;
newblock.x=10;
newblock.y=10;
addChild(newblock);
myarray[counter] = newblock; //adds a newblock object into array
counter += 1;
}
Then I have a loop with a currently primitive way of handling my problem:
stage.addEventListener(Event.ENTER_FRAME, gameloop);
function gameloop(evt:Event):void {
if (moveright==true){
myarray[0].x += 5;
myarray[1].x += 5;
myarray[2].x += 5
-(and so on)-
My question is how can I change x,y values every frame for new objects duplicated into the array, along with the previous ones that were added. Of course with a more elegant way than writing it out myself... array[0].x += 5, array[1], array[2], array[3] etc.
Ideally I would like this to go up to 500 or more array objects for one array so obviously I don't want to be writing it out individually haha, I also need it to be consistent with performance so using a for loop or something to loop through the whole array and move each x += 5 wouldn't work would it? Anyway, if anyone has any ideas that'd be great!
If you have to move 100 objects, you have to move them. No alternatives.
But what you can really do to save performance, is optimize the solution itself. A few cents from me:
Of course the loop has to be applied in your case, managing 100+ assignments line by line is definitely not the right way to go. Although you gain nothing performance wise with just using a loop.
Try grouping the objects. As I see above, you seem to be moving all those objects with similar increment. Group them all into larger movieclips (or Sprites) & move that instead.
Learn Blitting & caching methods to save a lot on performance, Or you would sooner or later hit on the road where your logic cannot be twisted anymore & performance will be a pain.
Also, in extent of the previous step, do consider using Sprite Sheets if you have multiple states of the same object.
Finally, I would also like to caution you to not waste time on micro optimizations & thinking about them.
You can use some container sprite and add the blocks to that on creation:
// Some init place
var blockContainer:Sprite = new Sprite();
addChild(blockContainer);
Make the blocks:
function makeblock(e:Event){
newblock=new block;
newblock.x=10;
newblock.y=10;
// Add the block to the container
blockContainer.addChild(newblock);
myarray[counter] = newblock; //adds a newblock object into array
counter += 1;
}
And the gameloop:
stage.addEventListener(Event.ENTER_FRAME, gameloop);
function gameloop(evt:Event):void {
if (moveright==true){
blockContainer.x += 5;
}
// etc...
}
This way you'll only have to move one object. Of course this method will only work so long as all the blocks need to move in the same direction. By the way, a for loop will work just as well - 500 iterations is nothing. The only performance issue will likely be just rendering and that will happen regardless of what method you choose, as you have to somehow move the blocks (in other words, performance here is not really the issue as you have to render the movement change, the only question is how you choose to implement the movement for your own coding convenience).
I am simulating a fast food restaurant over three hours. The three hours are divided into 18 intervals of 600 seconds each. Each interval outputs statistics about what happened on those 600 seconds.
My original structure was like this:
int i;
for (i=0; i<18; i++)
interval(customerArrive);
int interval(double customerArrive)
...
...
int t;
for (t=0;t<600;t++)
This method of two (for loops) doesn't work because it doesn't allow time to be a continuous function. If an event happens (as in, a customer arrives) in the first interval at t=599, then this event will not exist at t=601 because everything is erased as the second interval begins.
The way I want to approach this is to make a while loop to allow time to be a continuous function, I just don't know how to 'convert' my code to this.
Would it be something like this?
while (t<10800)
{
...
}
I'm not sure what the condition needs to be for this while loop to exit.
If necessary, here is my full code: http://pastebin.com/3ec0Ks9u
"May be",i understood your problem.If you want something to be monitored (continuous function in your words),u need to take help of threads and timers,which is out of your scope for now.If you want to use something basic,the question is not well understood,please re-construct it.
[…] everything is erased as the second interval begins.
That's not due to the two for loops, but instead due to the fact that the outer for loop calls a function, and you reinitialize stuff in that function. So move that outer for loop into the function interval (probably changing the method name along the way, as it no longer fits). In that method you can write
int i, t;
… // initialize stuff
for (i=0; i<18; i++) {
for (t=0;t<600;t++) {
… // do stuff
}
}
Those loops won't erase anything, and you won't have to compute the values of i and t from some single counter.
allow time to be a continuous function
Obviously, time will still be discretized in those steps. As it would in your while loop. If you dont want discrete time steps, you'll have to radically change your code, e.g. by computing the times when customers arrive up front, and then stepping from event to event instead of in fixed increments.
I have a 3500 lines long C function written by someone else that i need to break it apart without causing any regression. Since it is in C, the main problem i face is maintaining the state of the variables. For example if i break a small part of the code into another function, i will need to pass 10 arguments. Some of them will actually change inside the code of the new function. So effectively i will need to pass a pointer to them. It becomes very messy. Is there is better way of dealing with such refactoring? Any "best practice"?
Unit testing. Extract small portions of the code that depend on 3 variables or less (1 variable best) and test the hell out of it. Replace that code in original function with a call to new function.
Each function should do one thing that is easy to figure out from examining the code.
Instead of passing 10 variables around, put them into a structure and pass that around.
In my opinion, the best thing you can do is to thoroughly study that function, and fully understand its internals. It is more than probable that this function has a lot of anitpatterns inside it, so I'd not try to refactor it: once I knew how it works (which I understand this can suppose a lot of time) I'd throw it away and rewrite the equivalent smaller functions needed, from scratch.
Pack the local variables that are shared between multiple of the sub-functions into a struct and hand the struct around?
Are you stuck with C? I have sometimes converted such functions into a C++ class, where I convert the some (or all) local variables into member variables. Once this step has been done, you can easily break out part of the code into methods that work on the member variables.
In practice this means that a function like:
... do_xxx(...)
{
.. some thousand lines of code...
}
can be converted into:
class xxx_handler
{
public:
xxx_handler(...);
... run(...)
{
part1();
part2();
part3();
return ...;
}
private:
// Member variables goes here.
};
// New replacement function.
... do_xxx(...)
{
xxx_handler handler(...);
return handler.run(...);
}
One thing to start with, as a first step to taking out parts of the function as independent functions, is to move "function global" temp variables to be in tighter scope, something like:
int temp;
temp = 5;
while(temp > 0) {...}
...
temp = open(...);
if (temp < 0) {...}
converted to
{
int temp = 5;
while(temp > 0) {...}
}
...
{
int temp = open(...);
if (temp < 0) {...}
}
After that, it's easier to move each {} block into a separate function, which does one well-defined thing.
But then, most important guideline after having unit tests:
Use version control which supports "cherry-picking" (like git). Commit often, basically whenever it compiles after refactoring something, then commit again (or amend the previous commit if you don't want to have the first commit version around) when it actually works. Learn to use version control's diff tool, and cherry-picking, when you need to roll back after breaking something.
I have a need for an efficient sort that doesn't have a callback, but is as customizable as using qsort(). What I want is for it to work like an iterator, where it continuously calls into the sort API in a loop until it is done, doing the comparison in the loop rather than off in a callback function. This way the custom comparison is local to the calling function (and therefore has access to local variables, is potentially more efficient, etc). I have implemented this for an inefficient selection sort, but need it to be efficient, so prefer a quick sort derivative.
Has anyone done anything like this? I tried to do it for quick sort, but trying to turn the algorithm inside out hurt my brain too much.
Below is how it might look in use.
// the array of data we are sorting
MyData array[5000], *firstP, *secondP;
// (assume data is filled in)
Sorter sorter;
// initialize sorter
int result = sortInit (&sorter, array, 5000,
(void **)&firstP, (void **)&secondP, sizeof(MyData));
// loop until complete
while (sortIteration (&sorter, result) == 0) {
// here's where we do the custom comparison...here we
// just sort by member "value" but we could do anything
result = firstP->value - secondP->value;
}
Turning the sort function inside out as you propose isn't likely to make it faster. You're trading indirection on the comparison function for indirection on the item pointers.
It appears you want your comparison function to have access to state information. The quick-n-dirty way to create global variables or a global structure, assuming you don't have more than one thread going at once. The qsort function won't return until all the data is sorted, so in a single threaded environment this should be safe.
The only other thing I would suggest is to locate a source to qsort and modify it to take an extra parameter, a pointer to your state structure. You can then pass this pointer into your comparison function.
Take an existing implementation of qsort and update it to reference the Sorter object for its local variables. Instead of calling a compare function passed in, it would update its state and return to the caller.
Because of recursion in qsort, you'll need to keep some sort of a state stack in your Sorter object. You could accomplish that with an array or a linked-list using dynamic allocation (less efficient). Since most qsort implementations use tail recursion for the larger half and make a recursive call to qsort for the smaller half of the pivot point, you can sort at least 2n elements if your array can hold n states.
A simple solution is to use a inlineble sort function and a inlineble compare callback. When compiled with optimisation, both call get flatten into each other exactly like you want. The only downside is that your choice of sort algorithm is limited because if you recurse or alloc more memory you potentially lose any benefit from doing this. Method with small overhead, like this, work best with small data set.
You can use generic sort function with compare method, size, offset and stride.This way custom comparison can be done by parameter rather then callback. With this way you can use any algorithm. Just use some macro to fill in the most common case because you will have a lot of function argument.
Also, check out the STB library (https://github.com/nothings/stb).
It has sorting function similar to this among many other useful C tools.
What you're asking for has already been done -- it's called std::sort, and it's already in the C++ standard library. Better support for this (among many other things) is part of why well-written C++ is generally faster than C.
You could write a preprocessor macro to output a sort routine, and have the macro take a comparison expression as an argument.
#define GENERATE_SORT(name, type, comparison_expression) \
void name(type* begin, type* end) \
{ /* ... when needed, fill a and b and use comparison_expression */ }
GENERATE_SORT(sort_ints, (*a<*b))
void foo()
{
int array[10];
sort_ints(array, array+10);
}
Two points. I).
_asm
II). basic design limits of compilers.
Compilers have, as a basic purpose, the design goal of avoiding assembler or machine code. They achieve this by imposing certain limits. In this case, we give up a flexibility that we can easily do in assembly code. i.e. split the generated code of the sort into two pieces at the call to the compare function. copy the first half to somewhere. next copy the generated code of the compare function to there, just after the previous copied code of the first part. then copy the last half of the sort code. Finally, we have to deal with a whole series of minor details. See also the concept of "hot patching" running programs.