OPTIMASI TEKNIK PEMROGRAMAN

Posted in Labels:

OPTIMASI TEKNIK PEMROGRAMAN

Menyambung artikel optimasi teknik pemrograman yang telah ditulis pada edisi sebelumnya, mari kita mempelajari teknik selanjutnya! Joko Nurjadi

BAGIAN 2 DARI 2 ARTIKEL
KALAU PADA edisi lalu telah dibahas teknik optimasi untuk kondisi else, perulangan yang bercabang, juga regular expression, maka pada edisi ini kita akan membahas mengenai pemanfaatan memory, rekursif, dan teknik lainnya.
Memory
Membuat program berkaitan erat dengan data, bahkan statement 1 + 2 pun sudah menggunakan data (yaitu angka 1 dan 2) yang menghasilkan output 3 karena diolah dengan operator +.
Contoh di atas menggambarkan input -> proses -> output. Input dapat berupa database relasional, file, ataupun entry pengguna. Jika data berukuran besar, mungkin akan membuat program Anda berpikir keras sampai akhirnya menampilkan output yang diharapkan.
Salah satu cara untuk mempercepat waktu pemrosesan aplikasi adalah dengan menggunakan memory sebagai penampung, karena kecepatan akses memory secara umum melebihi kecepatan akses disk. Contoh sederhana seperti potongan program Visual Basic di bawah ini:
Open “dummy.txt” For Input As #1
Do While Not EOF(1)
Line Input #1, sTemp
Loop
Close #1
Program di atas membuka file dummy.txt, dan melakukan perulangan do while untuk membaca isi file per baris. Sebagai gambaran, proses di atas dilakukan pada sebuah file text dengan ukuran 46 MB.
Pada komputer penulis, program selesai membaca seluruh isi file dalam waktu kurang lebih 4 detik. Memory usage yang terlihat dari Windows Task Manager saat mengeksekusi program ini kurang lebih sebesar 3,6 MB.
Program tersebut dapat dioptimasi untuk mendapatkan kinerja yang lebih cepat, tentu saja waktu 4 detik yang dapat dilakukan program tersebut relatif sudah cukup cepat, tetapi jika proses tersebut dilakukan dengan frekuensi yang tinggi, anggaplah dijalankan 100 kali, maka logikanya waktu yang diperlukan menjadi 100 x 4 detik atau 400 detik.
Proses dapat dioptimasi menjadi lebih cepat secara signifikan dengan melakukan modifikasi sebagai berikut:
Open “dummy.txt” For Binary As #1
sTemp = Space$(LOF(1))
Get #1, , sTemp
Close #1
Perbedaan program ini dengan sebelumnya adalah, file dibuka dalam mode binary, dan seluruh isinya langsung ditampung ke dalam sebuah variabel, tidak dibaca per baris, sehingga konsekuensinya Anda memerlukan memory penampung yang relatif besar.
Lalu, bagaimana hasilnya? Saat dijalankan berkali-kali, range waktu yang dibutuhkan berkisar dari 1,1 detik – 1,8 detik. Jauh lebih cepat, bukan? Efek sampingnya, memory usage pada saat eksekusi tercatat mencapai 98 MB!
Prinsipnya, Anda dapat memanfaatkan memory untuk mempercepat proses, tetapi perhitungkan bahwa program Anda akan menyita memory yang relatif besar yang bisa jadi melewati batas penggunaan memory sehingga menimbulkan error.
Kasus di bawah ini menunjukkan lebih jauh penggunaan memory. Perhatikan potongan program Visual Basic berikut:
For i = 1 To 10000
txt.Text = txt.Text & i
Next
Asumsinya Anda memiliki sebuah control textbox bernama txt, program di atas melakukan perulangan sebanyak 10.000 kali dan menampung isi variabel i ke dalam control txt.
Pengukuran yang dilakukan penulis menunjukkan program tersebut membutuhkan waktu rata-rata sekitar 14 detik sampai dengan 16 detik pada beberapa percobaan.
Modifikasi dengan memanfaatkan memory sebagai buffer seperti di bawah ini akan meningkatkan kecepatan proses:
For i = 1 To 10000
buffer = buffer & i
Next
txt.Text = buffer
Program di atas akan menampung terlebih dahulu isi variabel i pada perulangan for di dalam sebuah variabel yang bertindak sebagai buffer, setelah perulangan berakhir, isi dari buffer diberikan pada control txt. Hasilnya program ini hanya membutuhkan waktu kurang dari 0.5 detik dalam setiap percobaan yang dilakukan.
Jangan lupa untuk selalu membandingkan performa sebelum dan sesudah optimasi, dan apakah output tidak berubah dari yang diharapkan. Karena sering ditemui banyak faktor X yang berpengaruh yang baru dapat kita ketahui setelah mempraktikkannya.
Rekursif
Rekursif merupakan sebuah teknik pemanggilan function yang memanggil dirinya sendiri. Anggaplah Anda memiliki function sederhana menuliskan sebuah kalimat pada layar/console, sebelum function itu berakhir, Anda menyisipkan perintah untuk memanggil function itu sendiri, inilah sebuah contoh rekursif sederhana, yang bahkan dapat dibuat pada batch file sebagai berikut:
@echo off
echo “Selamat pagi”
rekursif.bat
Simpan script di atas pada sebuah fi le bernama rekursif.bat, apa yang terjadi saat Anda menjalankan rekursif.bat?
Tentunya pada layar/console akan tertulis kalimat tersebut secara terus-menerus, yang tidak terbatas banyaknya jika Anda tidak memberikan kondisi kapan program berhenti memanggil dirinya sendiri.
Istilah GNU (GNU’s Not Unix) dan PHP (PHP: Hypertext Pre-processor) juga merupakan contoh rekursif, karena memanggil dirinya sendiri.
Pada banyak kasus, function rekursif yang belum dirilis dari memory saat memanggil dirinya sendiri, akan membuat tumpukan (stack) yang memenuhi memory dan dapat mengakibatkan komputer Anda bengong alias hang.
Apakah teknik rekursif selalu membawa dampak negatif seperti penggunaan memory yang boros?Tidak juga, keuntungan menggunakan rekursif adalah kode program yang singkat, pemecahan masalah yang lebih mudah (untuk beberapa kasus), dan mungkin cocok bagi Anda yang gemarmengasah logika.
Contoh fungsi rekursif yang biasanya selalu ada dalam bahasan rekursif, adalah contoh fungsi menghitung faktorial sebagai berikut:
Function Fakto(ByVal n As Integer) As Long
If n <= 1 then
Fakto = 1
Else
Fakto = n * Fakto(n – 1)
End if
End Function
Walaupun contoh di atas menunjukkan dengan tepat cara kerja rekursif (silakan lakukan debug/trace perbaris untuk mempelajarinya dengan lebih detail), tetapi tidak menunjukkan keunggulan signifikan rekursif dibandingkan nonrekursif atau perulangan/iterasi biasa. Kita dapat membuat program faktorial nonrekursif dengan mudah seperti berikut:
Function Fakto_NonRekursif(ByVal n As Integer) As Long
Dim i As Integer
Dim result As Long
result = 1
For i = n To 1 Step -1
result = i * result
Next
Fakto_NonRekursif = result
End Function
Untuk melihat keunggulan rekursif yang cukup optimal, contoh yang tepat adalah implementasi Quick Sort ataupun permainan Menara Hanoi, yang memungkinkan pemecahan masalah secara rekursif dengan algoritma divide and conquer, artinya membagi problem ke dalam kemungkinan-kemungkinan subproblem dan menyelesaikannya, suatu hal yang relative lebih sulit dilakukan dengan perulangan/iterasi biasa.
Code Refactoring
Berbeda dengan tulisan tangan yang rata-rata masih dapatdibaca (paling tidak oleh penulisnya) walaupun ditulis bertahuntahun yang lalu, kode program bisa jadi sukar dipahami kembali setelah sekian lama, termasuk oleh programernya sendiri!
Bukan hal yang aneh jika kita melihat (atau mengalami sendiri) seorang programer berusaha mempelajari kode program yang baru dibuatnya sekitar dua minggu yang lalu. Karena itu, optimasi juga bisa dilakukan dengan tujuan untuk membuat kode Anda lebih terbaca, salah satu teknik yang dikenal untuk keperluan ini adalah code refactoring. Pada metodologi seperti Extreme Programming, refactoringmerupakan bagian dari siklus pengembangan software.
Mengapa kode program dapat menjadi sulit terbaca? Contoh sederhananya saja, kebiasaan menuliskan nama variable dengan singkat, misalnya i untuk variabel bertipe integer, suntuk variabel bertipe string. Kadang kalau variabel i sudah digunakan, maka dilanjutkan dengan variable j, k, l, m, dan seterusnya.
Semakin panjang kode program Anda, akan semakin sulit untuk didebug dan ditelusuri alurnya, dalam kondisi ini, nama variable yang merepresentasikan fungsinya akan dapat membantu pema- haman, misalnya variabel bernama diskon, total, bunga,pajak, tentunya lebih mudah untuk dipahami.
Program yang sulit dipahami, otomatis akan sulit untuk diperbaiki, dimodifikasi, ataupun diberikan modul tambahan. Di saat seperti inilah, penggunaan code refactoring menjadi salah satu isu penting.
Contoh code refactoring yang lain adalah membuat susunan program menjadi terstruktur, misalnya mengubah kode didalam blok if menjadi subrutin, ataupun menghapus code yang tidak diperlukan (dead code), misalnya menghapus variabel yang dideklarasi tetapi tidak pernah digunakan.
Beberapa IDE bahasa pemrograman memiliki dukungan untuk melakukan refactoring secara otomatis, antara lain adalahVisual Studio 2008, CodeGear Delphi, atau NetBeans.
API
Beberapa bahasa pemrograman high-level memiliki dukungan terhadap API atau Application Programming Interface, yaitu sekumpulan function yang disediakan operating system atau berasal dari sebuah service/library.
API sebagai sebuah function yang siap digunakan (walau tidak selalu mudah untuk diimplementasikan), dapat membantu Anda untuk mempercepat proses development dan mempermudah Anda melakukan eksplorasi lebih jauh. Contohnya, Anda dapat membuat sebuah aplikasi yang mengakses hardware tertentu dengan menggunakan API yang disediakan didalam SDK hardware tersebut.
Di bawah ini merupakan contoh penggunaan function API yang disediakan oleh operating system Windows (Windows API) untuk mendapatkan nama komputer, contoh dalam Visual Basic. Letakkan deklarasi function API berikut pada bagian Declarations:
Private Declare Function GetComputerName Lib “kernel32”
Alias “GetComputerNameA” ( _
ByVal lpBuffer As String, _
nSize As Long) As Long
Contoh pemanggilan function tersebut adalah:
Dim sBuffer As String
Dim nSize As Long
Dim lResult As Long
nSize = 2048
sBuffer = Space(248)
lResult = GetComputerName(sBuffer, nSize)
MsgBox sBuffer
Hal yang perlu diperhatikan dalam menggunakan API adalah apa yang sering diajarkan saat pertama kali kita belajar bahasa pemrograman, yaitu simpan pekerjaan sesering mungkin. Bukan untuk menunjukkan ketidakpercayaan Anda pada PLN, tetapi karena function API dapat saja menyebab-kan crash karena pemanggilan yang salah atau kegagalan pengaksesan.
Right Technique at The Right Time
Optimasi baru dapat dikatakan berhasil jika Anda menggunakan sebuah teknik pemrograman pada saat yang tepat. Jadi tidak berarti kalau kita menguasai suatu teknik pemrograman, maka teknik tersebut selalu tepat jika diimplementasikan pada setiap kasus.
Hal ini dikembalikan lagi pada tujuan utama pembuatan program yang tentu bervariasi, dalam kompetisi pemrograman mungkin tujuan Anda membuat program dengan output yang benar dalam waktu secepat mungkin, dalam bidang pengajaran Anda akan berusaha membuat program yang mudah dibaca dan dimengerti.
Jangan lupakan juga peran pengguna program Anda, yang bisa jadi akan berinteraksi dengan aplikasi buatan Anda lebih lama dibandingkan Anda sendiri. Ambil saja sebuah contoh: mungkin pengguna perlu diberikan splash screen yang bersahabat pada saat program pertama kali dieksekusi.
Tentunya jika dilakukan pengukuran yang presisi, splash screen membutuhkan proses tambahan sehingga memperlambat proses keseluruhan, tetapi bagi pengguna yang memandang tepat di depan monitor, splash screen dapat menyembunyikan proses yang terjadi pada background sehingga pengguna tidak merasa menunggu.
Berhasil menerapkan right techique at the right time, akan memberikan kepuasan tersendiri bagi Anda yang memilih hobi pada bidang pemrograman
LEBIH LANJUT
http://www.codeproject.com/KB/recipes/Iterative_vs_Recursive.aspx
http://en.wikipedia.org/wiki/Dynamic_programming
http://en.wikipedia.org/wiki/Refactoring