cperformancesortingoptimizationbubble-sort

How I can do a optimization for printing a large chunk of text?


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?


Solution

  • The first things that can be fixed are:

    1. Compile with -O2 if you don't do that already. (turn the optimizations on)

    2. 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.

    3. 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.

    4. 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.