Uso delle macro per implementare un vettore generico (array dinamico) in C. Questa è una buona idea?

5

Finora ho fatto solo progetti personali a casa. Spero di essere coinvolto in qualche progetto open source qualche volta il prossimo anno. I linguaggi che ho usato di più sono C e C ++. Ho usato entrambe le lingue per oltre un anno e mi sento come se fossi diventato abbastanza abile con entrambi, ma non so davvero quale mi piace di più.

Personalmente mi piace C perché penso sia semplice ed elegante. Per me il C ++ sembra gonfiato di molte funzioni inutili che complicano solo il processo di progettazione. Un altro motivo per cui mi piace usare la C semplice è che sembra essere più popolare nel mondo del software libero e open-source.

La caratteristica che mi manca di più del C ++ quando uso C semplice è probabilmente il std::vector di STL (Standard Template Library).

Non ho ancora capito come dovrei rappresentare gli array in crescita in C. Fino a questo punto ho duplicato il mio codice di allocazione della memoria ovunque nei miei progetti. Non mi piace la duplicazione del codice e so che è una cattiva pratica, quindi non mi sembra una soluzione molto buona.

Ho pensato a questo problema ieri e mi è venuta l'idea di implementare un vettore generico usando le macro del preprocessore.

Sembra questo:

int main()
{
    VECTOR_OF(int) int_vec;
    VECTOR_OF(double) dbl_vec;
    int i;

    VECTOR_INIT(int_vec);
    VECTOR_INIT(dbl_vec);

    for (i = 0; i < 100000000; ++i) {
        VECTOR_PUSH_BACK(int_vec, i);
        VECTOR_PUSH_BACK(dbl_vec, i);
    }

    for (i = 0; i < 100; ++i) {
        printf("int_vec[%d] = %d\n", i, VECTOR_AT(int_vec, i));
        printf("dbl_vec[%d] = %f\n", i, VECTOR_AT(dbl_vec, i));
    }

    VECTOR_FREE(int_vec);
    VECTOR_FREE(dbl_vec);

    return 0;
}

Utilizza le stesse regole di allocazione di std::vector (la dimensione inizia come 1 e poi raddoppia ogni volta che è necessario).

Con mia sorpresa ho scoperto che questo codice viene eseguito più di due volte più veloce dello stesso codice scritto usando std::vector e genera un eseguibile più piccolo! (compilato con GCC e G ++ utilizzando -O3 in entrambi i casi).

La mia domanda è:

  • Consiglieresti di usarlo in un progetto serio?
  • In caso contrario, mi piacerebbe che spiegassi perché e quale alternativa migliore sarebbe.
posta wefwefa3 30.12.2014 - 13:44
fonte

1 risposta

2

My question is: Would you recommend using this in a serious project?

Sì! Ecco qualcosa che è per lo più vero per le funzioni di libreria: devono necessariamente essere generalmente applicabili al fine di soddisfare molti utenti con esigenze diverse. Se si conosce l'algoritmo sottostante, la funzione della libreria sarà più grande e più lenta della propria implementazione. La maggior parte delle volte non ci interessa, perché le dimensioni e la velocità non sono un problema. Tuttavia, una volta che la velocità diventa un problema e il collo di bottiglia è la funzione di libreria (molto spesso con algoritmi di ordinamento della libreria), la semplice comprensione dell'algoritmo e la scrittura di qualcosa che funziona per te può portare a miglioramenti della velocità. Capisco che tu l'abbia scoperto in un altro modo (riproducendo una funzione da std::vector in C) e non stai facendo una domanda di ottimizzazione. Ma vale la pena ricordare che ciò che hai appreso sarà molto utile in futuro quando lavori in Java, C ++, ecc. E ti imbatti in un collo di bottiglia veloce che schiaccia il tuo progetto. Questo può accadere spesso in progetti ad alta intensità di calcolo.

    
risposta data 31.12.2014 - 18:52
fonte

Leggi altre domande sui tag