Optimasi fungsi Math.Exp dan Math.Pow di C#


Karena tidak ada kerjaan semalam jadi iseng2 ja nyari artikel tentang optimasi di C#, maklumlah ane kan programmer C#.šŸ˜€. Setelah mencari-cari ternyata nemu cara optimasi yang aneh tapi bener sip. Pertama kali yang saya bahas disini yaitu fungsi exponensial. Dalam C# sudah ada fungsi yang menangani perpangkatan exponensial, tp itu belum cukup optimal karena ada cara lain yang lebih cepat dalam menghitung e^val.

		public static double Exp(double val) {
    		long tmp = (long) (1512775 * val + (1072693248 - 60801));
    		return BitConverter.Int64BitsToDouble(tmp << 32);
		}

Dengan cara seperti fungsi diatas bisa mempercepat waktu komputasi dari 1095ms ke 891ms untuk proses perhitungan 10 proses perpangkatan exponensial. Lumayan kan bisa mengurangi waktu sampai 20%. Tetapi untuk testcase yang sdkit, justru dengan Math.Exp bisa lebih baik dan jika fungsi exp baru diatas lebih baik itu pun tidak terlalu signifikan.šŸ™‚

Tapi untuk pangkat exponensial cuma nemu 1 cara, klo anda nemu yang lebih baik. Tolong saya dikasih linknya!šŸ™‚. Sekarang beralih ke perpangkatan atau fungsi power.Ā  Langsung saja saya ke source code nya…

public static double Exp(double val) {
 long tmp = (long) (1512775 * val + (1072693248 - 60801));
 return BitConverter.Int64BitsToDouble(tmp << 32);
 }

 public staticĀ  double pow(double a, double b) {
 long tmp = (long) (9076650 * (a - 1) / (a + 1 + 4 * (Math.Sqrt(a))) * b + 1072632447);
 return BitConverter.Int64BitsToDouble(tmp << 32);
 }

 public static double PowerA(double a, double b) {
 long tmp = (long)(BitConverter.DoubleToInt64Bits(a) >> 32);
 long tmp2 = (long)(b * (tmp - 1072632447) + 1072632447);
 return BitConverter.Int64BitsToDouble(((long)tmp2) << 32);
 }

Iterasi Math.Pow pow PowerA pow2
100000 31 16 16 15
1000000 219 172 141 172
10000000 2219 1797 1375 1797

Tabel diatas merupakan hasil dari benchmark dengan menggunakan proses simple yang melibatkan fungsi-fungsi power diatas. Dan dari tabel tersebut fungsi yang terbaik yaitu fungsi PowerA. Untuk lebih jelasnya, berikut adalah code yang saya gunakan untuk benchmark fungsi diatas.

using System;

namespace benchmark
{
 class Program
 {
 public static double Exp(double val) {
 long tmp = (long) (1512775 * val + (1072693248 - 60801));
 return BitConverter.Int64BitsToDouble(tmp << 32);
 }

 public staticĀ  double pow(double a, double b) {
 long tmp = (long) (9076650 * (a - 1) / (a + 1 + 4 * (Math.Sqrt(a))) * b + 1072632447);
 return BitConverter.Int64BitsToDouble(tmp << 32);
 }

 public static double PowerA(double a, double b) {
 long tmp = (long)(BitConverter.DoubleToInt64Bits(a) >> 32);
 long tmp2 = (long)(b * (tmp - 1072632447) + 1072632447);
 return BitConverter.Int64BitsToDouble(((long)tmp2) << 32);
 }

 public staticĀ  double pow2(doubleĀ  a,Ā  double b) {
 double x = (BitConverter.DoubleToInt64Bits(a) >> 32);
 long tmp2 = (long) (1512775 * (x - 1072632447) / 1512775 * b + (1072693248 - 60801));
 return BitConverter.Int64BitsToDouble(tmp2 << 32);
 }

 public static void Main(string[] args)
 {
 double b=0;

 for(int x=10000;x<100000000;x*=10){
 Console.WriteLine("jumlah Iterasi {0}",x);
 int awal = Environment.TickCount;
 for(int a=0;a<x;a++){
 b= Math.Exp(a);
 }
 Console.WriteLine("Math.Exp =Ā  {0}",(Environment.TickCount-awal));
 benchmark bb = new benchmark();

 awal = Environment.TickCount;
 for(int a=0;a<x;a++){
 b= Exp(a);
 }
 Console.WriteLine("Exp = {0}",(Environment.TickCount-awal));

 awal = Environment.TickCount;
 for(int a=0;a<x;a++){
 b= Math.Pow(a,a);
 }
 Console.WriteLine("Math.Pow = {0}",(Environment.TickCount-awal));

 awal = Environment.TickCount;
 for(int a=0;a<x;a++){
 b= pow(a,a);
 }
 Console.WriteLine("pow = {0}",(Environment.TickCount-awal));

 awal = Environment.TickCount;
 for(int a=0;a<x;a++){
 b= benchmark.PowerA(a,a);
 }
 Console.WriteLine("PowerA = {0}",(Environment.TickCount-awal));

 awal = Environment.TickCount;
 for(int a=0;a<x;a++){
 b= pow2(a,a);
 }
 Console.WriteLine("pow2 = {0}",(Environment.TickCount-awal));
 }
 Console.ReadKey(true);
 }
 }
}

Spesifikasi perangkat keras yang digunakan ditunjukkan pada tabel dibawah ini.

Processor IntelĀ® PentiumĀ® DUAL CPU T2310 @1.46GHz
Memory 896MB RAM
OS Windows XP Professional SP 3
Environtment .Net Framework 3.5 sp 1

Semoga bermanfaat,Ā  klo da cara yang lebih baik dari metode diatas tolong kasih tau saya juga ya….:)

5 thoughts on “Optimasi fungsi Math.Exp dan Math.Pow di C#

      1. bahasa Indonesia yang benar adalah silakan, tanpa ada h.
        semoga tidak menjadi efek domino, banyak yang salah tulis dan meniru yang salah tsb. usahakan selalu meniru yang benaršŸ™‚

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s