How to speed up my hash algorithm

My question is related to the task from CS50, pset5. For those who do not know about this, I will try to explain. Nothing special. I just need to make a function that will go into the dictionary dictionary (it was written earlier, all the words in this file are capitalized), which contains more than 20K words and sort them somehow. I made a simple and naive algorithm by creating a hash table that sort words, depending on their first letters. And I went through all the checks on the CS50, so my program works well. But compared to the course, one is too slow. The lead time for staff is 0.1 s, but for mine - 5.0 s - 7.0 s. What can I improve in this code to make it faster? Or should I completely change everything? I have no experience in optimization, because I just started to learn. It would be great to learn from any of you =) Thanks in advance!

// Some constant values, which are declared before the function
#define LENGTH  46
#define ALPHALENGTH  26
/* Definition of node struct. Nothing special, in fact =) */
typedef struct node {
    char word[LENGTH +1];
    struct node *next;
} node;

node *hashTable[ALPHALENGTH];

bool load(const char *dictionary) { 
    FILE *f = fopen(dictionary, "r");

    if (f == NULL) {
        return false;
    }

    char word[LENGTH + 1];    
    int hash = 0;

    for (int i = 0; i < ALPHALENGTH; i++) {
        hashTable[i] = NULL;
    }

    // 46 - is LENGTH, but for some reason it is impossible 
    // to put variable`s name between quotation marks
    while (fscanf(f, "%46s", word) == 1) {
        // make every letter lowercase to get result from 0 - 25
        hash = tolower(word[0]) - 'a';
        node *new_node = malloc(sizeof(node));
        strcpy(new_node->word, word);

        // check if element is first in the list
        if (hashTable[hash] == NULL) {
            new_node->next = NULL;
            hashTable[hash] = new_node;
        } else {
            node *ptr = hashTable[hash];

            do {
                if (ptr->next == NULL) {
                    break;
                }
                ptr = ptr->next;
            } while (true);

            ptr->next = new_node;
            new_node->next = NULL;
        }
    }

    fclose(f);

    return true;
}
+4
2

-, -, : O (N 2).

, - , . , . , .

, , .

20 50 ( CS50):

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LENGTH  46
#define ALPHALENGTH  26
typedef struct node {
    struct node *next;
    char word[LENGTH +1];
} node;

node *hashTable[ALPHALENGTH];

bool load(const char *dictionary) {
    FILE *f = fopen(dictionary, "r");

    if (f == NULL) {
        return false;
    }

    char word[LENGTH + 1];
    int hash = 0;

    for (int i = 0; i < ALPHALENGTH; i++) {
        hashTable[i] = NULL;
    }

    while (fscanf(f, "%46s", word) == 1) {
        node *new_node = malloc(sizeof(node));
        if (new_node == NULL)
            return false;
        // make every letter lowercase to get result from 0 - 25
        hash = tolower(word[0]) - 'a';
        strcpy(new_node->word, word);
        /* prepending to the list */
        new_node->next = hashTable[hash];
        hashTable[hash] = new_node;
    }

    for (int i = 0; i < ALPHALENGTH; i++) {
        node *n, *prev, *next;
        /* reverse list */
        for (prev = NULL, n = hashTable[i]; n != NULL; ) {
            next = n->next;
            n->next = prev;
            prev = n;
            n = next;
        }
        hashTable[i] = prev;
    }

    fclose(f);

    return true;
}

void save(void) {
    for (int i = 0; i < ALPHALENGTH; i++) {
        for (node *n = hashTable[i]; n != NULL; n = n->next) {
            puts(n->word);
        }
    }
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        if (load(argv[1]))
            save();
    }
}

fscanf() fgets() .

+1

-; - .

26 - 20 000 . 750 1000 . (, , . , "t20 > q) .)

1000 (), 20 . -; , , . ( , , 1000.)

+5

All Articles