Optimasi Pemrograman dengan Bahasa C

Kali ini saya akan menulis tentang pemrograman dengan bahasa C. Ya, meskipun ini bukan bahasa ibu saya, setidaknya saya pernah mempraktikkan bagaimana melakukan optimasi kode sehingga hasilnya lebih efisien. Optimasi ini saya kelompokkan menjadi tiga kelompok, yaitu optimasi kode, algoritma, dan kompilasi.

Optimasi kode. Yang masuk di kelompok ini meliputi pemilihan sintaks dalam bahasa C.

  1. Gunakan variabel unsigned int atau register unsigned int ketimbang int jika nilai integer yang kita pakai tidak pernah negatif. Pada sebagian besar compiler operasinya lebih cepat.
    register unsigned int variable_name;
  2. Operasi aritmetik menggunakan integer jauh lebih cepat daripada dengan floating point (angka desimal). Jadi, untuk angka dengan ketelitian dua angka di belakang koma (misalnya akuntansi), yang biasanya hanya dioperasikan dengan tambah, kurang, kali (tanpa bagi), buat saja integer. Nanti tinggal komanya digeser.
  3. Lakukan operasi pembagian  (div) dan sisa (mod) dalam satu perintah. Operasi pembagian pada dasarnya menghasilkan dua nilai sekaligus: hasil bagi dan sisanya.
    int func_div_and_mod (int a, int b) {
            return (a / b) + (a % b);
        }
  4. Gunakan operasi shift untuk pembagian dan perkalian dengan angka pangkat dua.
    a = b >> 2;          // = b / 4  -> 4 = 2^2
    b = c << 5;          // = c * 32 -> 32 = 2^5
    c = d << 5 - d << 3; // = d * 24 -> 24 = 2^5 - 2^3
  5. Kurangi penggunaan variabel global sebisa mungkin. Variabel global tidak bisa disimpan di register. Oleh karena itu, kalaupun terpaksa memakai variabel global, salin nilainya pada variabel lokal.
    void func1( int *data )
        {
            int i;
            int localdata;
    
            localdata = *data; // variabel di salin di sini
            for(i=0; i<10; i++)
            {
                  anyfunc ( localdata, i);
            }
        }
  6. Gunakan switch pada kasus if-else yang jumlahnya 3 atau lebih.
  7. Pada operasi switch, gunakan variabel integer ketimbang char untuk case condition-nya.
  8. Gunakan looping mundur untuk menggantikan looping maju pada iterasi menggunakan for.
    int fung_looping_maju (int n)
        {
            int i, fact = 1;
            for (i = 1; i <= n; i++) //setiap iterasi selalu memeriksa dengan variabel, apakah i <= n
              fact *= i;
            return (fact);
        }
    
        int fung_looping_mundur(int n)   // yang ini lebih cepat
        {
            int i, fact = 1;
            for (i = n; i != 0; i--) //hanya sekali memeriksa dg variabel
               fact *= i;
            return (fact);
        }

    untuk sintaks

    for(i=n; i !=0; i--)

    bisa ditulis

    for(i=n; i--;)
  9. Untuk fungsi absolut, pakai cara tradisional daripada memanggil fungsi fabs.
    if(nilai<0) nilai= -nilai;
  10. Gunakan puts() ketimbang printf() jika tidak ada penggunaan parameter nilai.
  11. Gunakan perkalian ketimbang pembagian. Misalnya, lebih baik 7*0.25 ketimbang 7/4

Optimasi Algoritma. Optimasi ini meliputi strategi langkah-langkah operasi dalam kode program.

  1. Efisienkan looping. Kalau perintah-perintah bisa dikelompokkan dalam satu looping, satukan saja.
  2. Hindari pemanggilan function dalam looping. Modifikasi agar looping itu yang berada pada function. Sehingga function hanya dipanggil satu kali saja.
    for(i=0 ; i<100 ; i++)
        {
            func(t,i);
        }
    -------
    void func(int w,d)
        {
            lots of stuff.
        }

    Jadi

    func(t);
    ---
    void func(w)
       {
       for(i=0 ; i<100 ; i++)
       {
         //lots of stuff.
       }
    }
  3. Pada looping yang iterasinya kecil, misalnya 3 iterasi, tidak perlu memakai iterasi. Definisikan satu per satu.
  4. Gunakan __inline untuk fungsi yang kecil dan sering dipanggil.
    __inline int square(int x) {
           return x * x;
        }
    
        #include <MATH.H>
    
        double length(int x, int y){
            return sqrt(square(x) + square(y));
        }

Optimasi Kompilasi. Yang termasuk optimasi ini adalah bagaimana mengkompilasi agar file  executable menjadi optimal.

Gunakan opsi -O (“O” besar) pada saat kompilasi. Sintaksnya seperti ini

gcc -Olevel [options] [source files] [object files] [-o output file]

Olevel pada sintaks di atas terdiri atas beberapa opsi, seperti saya kutip pada [2] berikut:

Opsi Level optimization Waktu eksekusi Ukuran kode Penggunaan memori Waktu kompilasi
-O0 optimization for compilation time (default) + +
-O1 or -O optimization for code size and execution time + +
-O2 optimization more for code size and execution time + ++
-O3 optimization more for code size and execution time + +++
-Os optimization for code size ++
-Ofast O3 with fast none accurate math calculations + +++

Ket:
+ meningkat
++ lebih meningkat
+++ jauh lebih meningkat
– berkurang
— lebih berkurang
— jauh lebih berkurang

Untuk lebih dalam mengenai penjelasan optimisasi dengan compiler, bisa dirujuk di http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options

Referensi:

  1. Gosh, Koushik. (26 Februari 2004). Writing Efficient C and C Code Optimization. [Online]. Tersedia di: http://www.codeproject.com/Articles/6154/Writing-Efficient-C-and-C-Code-Optimization
  2. RapidTables.com. (). gcc -o / -O option flags. [Online]. Tersedia di: http://www.rapidtables.com/code/linux/gcc/gcc-o.htm

Sekian, semoga bermanfaat. Terima kasih..

Cipedes Tengah, 4 Juni 2013

Pos ini dipublikasikan di Developer dan tag , , . Tandai permalink.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s