Sunday, June 5, 2011

Optimasi Peng-eksekusi-an Branch (IF/SWITCH)

Baru mengaplikasikan teknik yang menurut gw pribadi cukup unik, yaitu optimasi eksekusi kode branch/conditional pada aplikasi yang punya main loop.

Misalkan gw punya aplikasi dengan potongan kode demikian:

Katakan method someMethod() dipanggil di dalam main loop. Method diatas tampak simpel, namun dari hal yang simpel tersebut mengandung potensial problem, khususnya ketika programmer melakukan salah ketik (katakanlah ia menulisnya "Login", bukan "login"). Sebenarnya dengan ketelitian yang tinggi, salah ketik bisa dihindari, namun manusia tetap manusia, sehingga kasus seperti ini, sebaiknya diserahkan ke komputer, seperti pada gambar berikut:
Pada gambar diatas, string di parse dengan parseEnum(String pInput) menjadi Enum Action. Dengan penggunaan enum, jadi dapat menggunakan switch, dan kesalahan typo akan mengakibatkan compile error. Compile error ini yang dimaksud menyerahkan ketelitian ke komputer.
Btw, anggap aja isinya parseEnum(String pInput) sudah benar ya, meski diatas hanya mengembalikan Unknown terus, hehe.

Pada realnya, someMethod1() isinya bisa sangat panjang, dan semakin panjang method, akan semakin sulit untuk dibaca oleh orang lain. Oleh karena itu, dapat dioptimasi lagi menjadi berikut:
Pada gambar diatas, diciptakan kelas abstract ActionWorker, yang nantinya akan memiliki kelas turunan yang bersesuaian dengan action yang ada. Pada optimasi ini, bahkan branching sudah tidak ada lagi di badan someMethod2(), sudah terenkapsulasi pada ActionWorker.ActionWorkerFactory(Action pInputEnum). someMethod2() menjadi sangat pendek jika dibandingkan dengan someMethod1().

Namun meski terenkapsulasi, branching SWITCH yang ada tetap terpanggil setiap kali loop. Apabila 1 detik terdapat 100 loop, akan terpanggil 100 kali. Optimasi selanjutnya adalah untuk mengurangi pemanggilan loop menjadi hanya 1 kali. Ya, terdapat cara untuk mengurangi menjadi hanya 1 kali, meski sebenarnya perlu dipanggil setiap loop.

Contohnya dapat dilihat pada gambar berikut:

Pada gambar diatas disertakan lagi enum Action, karena telah diubah sedikit, yaitu dengan menambahkan member mIntValue, konstruktor yang menerima parameter integer, dan method getIntValue()
selain itu, ditambahkan member ActionWorker[] mWorkers yang diinisiasi pada method init(). Method init() itu perlu di-invoke sekali sebelum main loop. Hasilnya, jadilah someMethod3()

sekilas someMethod3() mirip dengan someMethod2(). Bedanya terletak pada pen-assign-an tAppropriateWorker. Method someMethod3() hanya melakukan pengaksesan element pada suatu array, sedangkan method someMethod2() melakukan branching. Dengan begini, tidak ada lagi pemanggilan SWITCH pada main loop, yang digantikan dengan mengakses element array.

Sempet lakuin percobaan kecil-kecilan. Di java, branch dengan 1 kondisi lebih cepat daripada pengaksesan element array. Tapi mulai dari 2 kondisi dan seterusnya, pengaksesan element array lebih cepat. Selain itu, pengaksesan element array memiliki waktu konstan berapapun jumlah array yang ada, antara berisi 1 element dengan 1000 element, apabila diberikan index-nya, waktu aksesnya akan tetap.

Kalo ada yang kurang dimengerti, atau ada kesalahan, please kindly inform me by email, and thanks before. Semoga bermanfaat

No comments:

Post a Comment