So I was building a project that created a graph representing the bubble sort algorithm, but, the way I did is very slow and like to reorganize a vector with a hundred positions take about 3 minutes. This is the implementation:
void bubbleSort(int vet[]) { // Implementation of the bubble sort algorithm
int i, aux, troca;
do {
troca = 0;,
for (i = 0; i < VET_SIZE - 1; i++) {
createGraphic(vet);
if (vet[i] > vet[i+1]) {
aux = vet[i];
vet[i] = vet[i+1];
vet[i+1] = aux;
troca = 1;
}
}
} while (troca);
}
void createGraphic(int vet[]) { // Drawing the graphic
char graphic[VET_SIZE * (VET_SIZE * GRAPHIC_LENGHT + 1) + 1];
int i, j, k;
system("cls");
for (i = 0; i < VET_SIZE; i++) {
for (j = 0; j < VET_SIZE; j++) {
if (vet[j] - i > 0) {
graphic[i * (VET_SIZE * GRAPHIC_LENGHT + 1) + j * GRAPHIC_LENGHT] = '#';
for(k = 1; k <= GRAPHIC_LENGHT + 1; k++) { // Depending of the value of GRAPHIC LENGHT this part of the code print ' ' to give some spaces between he bars
graphic[i * (VET_SIZE * GRAPHIC_LENGHT + 1) + j * GRAPHIC_LENGHT + k] = ' ';
}
} else {
graphic[i * (VET_SIZE * GRAPHIC_LENGHT + 1) + j * GRAPHIC_LENGHT] = ' ';
for(k = 1; k <= GRAPHIC_LENGHT + 1; k++) {
graphic[i * (VET_SIZE * GRAPHIC_LENGHT + 1) + j * GRAPHIC_LENGHT + k] = ' ';
}
}
}
graphic[i * (VET_SIZE * GRAPHIC_LENGHT + 1) + VET_SIZE * GRAPHIC_LENGHT] = '\n';
}
graphic[VET_SIZE * (VET_SIZE * GRAPHIC_LENGHT + 1)] = '\0';
printf(GREEN "%s", graphic);
}
First I tried just printing the graphic character by character, but I saw that it was very slow, then I put the graphic in a vector and printed everything together, this is a little bit faster but still is not what a want. Can someone help me with some tool or code adjustment to make the graphic show instantly or faster then the current implementation?
The first things that can be fixed are:
Compile with -O2 if you don't do that already. (turn the optimizations on)
Instead of using system
function - put these 3 bytes at a start of your array - "\ec"
. It effectively does the same(if you use gnu/linux), but without overhead of system
call. System
call basically calls fork
underneath - not the good idea to do that every iteration.
Research the way to clear your screen on your machine with escape sequence, if "\ec"
doesn't work.
make array graphic
global or static.
Currently you have it on stack, and you basically recreate it every function call, which happens on every iteration of bubble sort loop.
Might not be that effective, but worth a try.
Also, what is VET_SIZE
and GRAPHIC_LENGTH
? If they are not something created with #define - you are using VLA, and it might slow your code down.
get rid of printf
and use write
syscall to directly output the buffer. Might not be that effective, but worth a try. Although, it might actually slow your code down, if you use a lot of writes. printf
, and all other stdio utilities basically accumulate input/output and write/read it rarely, so that syscalls are used sparingly. But if you don't need to do it often - just one big read
or write
- it's ok.
So, the general idea is to make every iteration of your loop a little less costly.
But the most effective thing would be to reconsider the algorithm of course. Show us some output of your program, so that we can see clearly what exactly you are doing. There are probably some better solutions.
Also, what's up with that comma?
troca = 0;,
Update on info from your comment:
You can "draw" graphical representation of array in advance and store them in a char **
in the same order as in your int vet
.
And when you are sorting, you remember which element was moved where, and you do the same swap operation to the char **
with graphical representation of the int vet
. That way you do not have to rebuild the graphical representation of an array, you just move pointers around and redraw.
For example, if an array is {3, 2, 1}
, then graphical representation array will be {"3 ###", "2 ##", "1 #"}
(I simplified a bit, but I hope you get the idea).
And when you sort and swap 3 and 2, you just swap the strings "3 ###" and "2 ##" in an array. Clear the screen, print.
If array has a lot of elements and you can not have graphical representation of every element in memory(which I doubt considering that it's not 1980 or something), you can remember instead some kind of description of graphical representation. Element value, amount of '#' symbols, something like that. And when you sort, you again swap the array of representation, and redraw it according to the description.