Apakah PyThon Lambat ? : Showdown 7 Bahasa Pemrograman


Semenjak SMU, saya pernah menggunakan/mempelajari beberapa bahasa pemrograman: Basic, Pascal, Visual Basic, C++, Fortran, ActionScript, Java, R, Matlab, PHP, dan baru kurang dari 1 bulan ini PyThon. Di Data Mining (bidang penelitian saat ini), pilihan bahasa pemrograman yang biasa digunakan adalah R, PyThon, C++, atau Matlab. Diluar itu library data mining/machine learning-nya terlalu sedikit. R saya keluarkan dari pilihan, karena akhir-akhir ini kebetulan sering bantu istri pakai R di riset PhDnya (Bayesian model), dan “bagi saya pribadi” pengalaman menggunakannya sangat tidak menyenangkan (baik dari performa maupun kemudahan dalam menggunakan). C++ is a beast, tapi codingnya kelamaan dan tidak multi-platform, saya diburu waktu untuk menyelesaikan pekerjaan secepat mungkin. C++ buat project penting saja, terutama saat ‘produksi’. Akhirnya untuk saat ini pilihannya jatuh ke Matlab atau PyThon ? Now let the duel begin … ??

Prakata Duel:

Selama ini saya lebih banyak memakai Matlab (pengalaman saya memakai Matlab sudah >10 tahun). Saya suka Matlab karena mudah pemakaiannya (bahkan pemrograman paralel bisa dilakukan hanya dengan satu baris), banyak fungsi (toolbox)nya, dan kebetulan punya license resmi. Namun ada beberapa hal yang membuat saya akhirnya memutuskan untuk berpindah dari bahasa pemrograman yang pernah menjadi No.1 di hati ini ^_^ :
  1. Kalau suatu saat mau membuat program komersil, licensing dan biayanya pasti makan hati,  jantung, dan paru-paru .. ?? ..
  2. Apakah Matlab cukup cepat ? … *ini yang paling membuat gundah di hati
  3. Matlab biasa digunakan untuk riset (riset communitynya besar), tapi apakah cocok untuk level produksi? Saya “ngeh” Matlab kurang cocok untuk produksi ketika saya kesulitan memakai driver NoSQL di Matlab.
Dari hasil Googling, performa PyThon “katanya” tidak bagus, malah sering di letakkan sebagai bahasa pemrograman paling lambat. Tapi belum lama ini juga menemukan bahwa Google banyak menggunakan PyThon, bahkan Youtube mostly di coding pakai PyThon, begitu juga DropBox dan beberapa software/system tenar lainnya.  Terakhir membaca Google merilis Big Data processing API enginenya (MapReduce) di Java dan PyThon (Link). Karena tidak terlalu suka dengan heap memory Java VM dan sulit melakukan pemrograman paralel di Java, akhirnya saya memutuskan untuk mencoba PyThon (walau menurut berbagai benchmark “katanya” lambat).Sebelum kita mulai test-nya, ada beberapa hal yang penting untuk diketahui:
  1. Aslinya PyThon dan Matlab (juga PHP) adalah Interpreter bukan compiler.
  2. But, wait a minute !… Matlab by default menggunakan JIT (Just In Time) compiler. untuk mematikan feature ini bisa dilakukan dengan perintah : “feature accel off” .
  3. Vectorization di Matlab juga “dibalik layar”  heavily optimized.
  4. PyThon dan Matlab sama-sama terkenal mudah untuk di pelajari/gunakan.

The Duel:

Supaya adil saya kepikiran untuk membuat “stupid function” sebagai pembanding (benchmark). Di dalam fungsi ini hanyalah perhitungan “ga jelas” menggunakan operasi dasar looping forwhile, dan logika “if” tanpa perhitungan vector/matrix. Saya bandingkan PyThon dan Matlab, keduanya menggunakan JIT dan tidak. Di PyThon saya mencoba dua macam JIT: Numba dan NumbaPro (kebetulan punya license resminya juga).Update: Saya juga melakukan perbandingan dengan bahasa pemrograman lain: PyThonMatlabRJavaC++Julia dan PHP. Semua source code yang digunakan dapat dilihat di sini (LINK)[Mohon koreksi jika ada yang salah dari code tersebut, Julia code contributed from Mas Rizal Fathony]. Beberapa baris di source code tersebut saya comment-out sebagai variasi eksekusi (e.g. Numba setting di PyThon dan accel on/off di Matlab).Daaannnn …. Eng ing eng … Berikut Hasilnya:
[caption id="attachment_6252" align="aligncenter" width="684"]Perbandingan Performa 7 Bahasa Pemrograman BenchMark 7 Bahasa Pemrograman terhadap Operasi Dasar (For, While, & if).[/caption] Ada beberapa catatan dari hasil tersebut:
  1. Tentu saja style coding akan mempengaruhi performa, namun coding yang saya gunakan dibuat se-dasar/basic mungkin.
  2. C++ sangat cepat, bahkan tidak terdeteksi dalam milli seconds, TAPIIIIIiiii…. kalau pakai optimasi -O2. Tanpa optimasi C++ butuh 10 detik. Artinya menggunakan bahasa pemrograman lower language memang cepat, tapi hanya kalau you know what you are doing. Untuk pemula/novice/newbie bisa-bisa C++ lebih lambat dari Matlab/PyThon kalau tidak tau cara ‘taming this beast‘.
  3. Dari hasil tersebut nampak bahwa PyThon jelas tidak lebih lambat dari Matlab. Baik Matlab VS Python tanpa JIT, maupun Matlab VS PyThon dengan JIT, nampak bahwa PyThon secara signifikan jauuuh lebih cepat.
  4. NumbaPro lebih cepat dari Numba biasa (yang gratis ?? ), Tapi “di contoh ini” bedanya tidak terlalu signifikan. Menurut saya, hanya kalau kecepatan/performa sangat vital di aplikasi (down to seconds), maka baru worth it untuk beli license versi Pro-nya.
  5. PyThon jika dilakukan dengan tepat “on par” dengan Java. Namun PyThon punya kelebihan di Module yang lebih lengkap, dan cenderung lebih mudah, termasuk pemrograman parallelnya.
  6. R seperti yang saya duga (dan selama ini rasakan), memang sangat lambat. Namun untuk mengembangkan model (Statistik/Machine Learning) R memang jagonya, karena package Statistik yang sangat lengkap. Cuma kalau sudah level produksi dengan data yang besar,…. yaaa…. terserah deh … ??
  7. Saya belum coba compiled PHP. Hasil PHP di atas adalah murni interpreter.
  8. Suprisingly Julia lebih lambat … benar-benar diluar dugaan …. need further investigation …

Salah Paham tentang PyThon:

Walau PyThon lebih lambat dari C, Java, atau Fortran. Akan tetapi PyThon punya versi compilernya juga (CyThon), mirip seperti di Matlab juga punya “Mex” function.  Artinya performa PyThon masih bisa di tingkatkan lebih jauh dengan relatif mudah dengan mengcompile-nya ke C menggunakan CyThon.Salah paham kedua yang sering terjadi adalah bagaimana Module di Python bekerja. beberapa user mungkin berfikir module PyThon “hanyalah” library (kumpulan) fungsi PyThon semata. Namun,… No …. beberapa module PyThon di optimasi dengan bahasa pemrograman yang lebih low level seperti C dan Fortran. Sebagai contoh Numpy, OpenBlast, SciPy, dan lain-lain. Jadi ketika kita menggunakan PyThon dan Modul-modul tersebut maka sebenarnya kita bisa memperoleh performa yang mirip dengan lower level programming language seperti C dan Fortran (Yess Fortran, you read that right). Banyak yang mencibir Fortran (karena memang Jadul), tapi performa dan akurasi Fortran termasuk yang paling wahid hingga saat ini.

ShowDown PyThon di Real-world Application – Text PreProcessing

Untuk menguji PyThon di Apikasi nyata yang sesungguhnya saya menggunakan 437.370 dokumen untuk di Pre-Process. Programnya dijalankan di sebuah PC biasa i7 QuadCore, RAM 16Gb. PreProcessing yang dilakukan adalah sebagai berikut:
  1. lowercase
  2. Symbols remover.
  3. Stopword Removal (Customized with >2000 words)
  4. Stemming
  5. Storing & Indexing ke NoSQL.
Module- Module yang saya gunakan: [1]. NLTK [2]. MultiProcess [3]. time [4]. os [5]. NoSQL Driver*Catatan: Saya tidak menggunakan optimasi CyThon atau bahkan JIT. Murni PyThon dan Module NLTK. Hasilnya saya rekam dalam video di bawah. Saya belum pernah mendapatkan hasil secepat ini di Matlab (Walau menggunakan Parallel juga “dan” JIT-on). Lebih dari 400ribu dokumen dalam jangka waktu kurang dari 2 menit (100 detik) menggunakan single node PC (bukan server/cluster/HPC).

Verdict: PyThon surely is NOT slow …. ??

The Source Codes

PyThon:

import time #,numba
from numbapro import autojit

@autojit(target="cpu")
def pungsi(N):
    j=0
    for i in range(N):
        j=i+100
        if(j%2==0):
            j=2
        while(j>N/10):
            j=j-10
        continue
    return i        
N=300000;
#start=time.time()
#hasil=pungsi(N)
#print('Total Processing Time Non JIT: %.2f seconds' % (time.time() - start))
start=time.time()

#dJIT=numba.jit(pungsi)
#hasil=dJIT(N)
hasil=pungsi(N)
print('Total Processing Time with JIT: %.2f seconds, hasil=%d' %((time.time()-start),hasil))

Matlab

clc;clear all;close all;fclose('all');
feature accel on
tic
N=300000;j=0;
for i=1:N
    j=i+100;
    if mod(j,2)==0
        j=2;
    end
    while j>N/10
        j=j-10;
    end
end
toc

PHP

<?php

function fs($N)
{  $j=0;
    for ($i=0;$i<$N;$i++)
    { $j=$i+100;
 if ($j%2==0)
   {$j=2;}
 while($j>$N/10)
   {$j=$j-10;}
    }    
    return $i;
}

$mulai=microtime(true);
$N=300000;
$hasil=fs($N);
$akhir=microtime(true);
$waktu=$akhir-$mulai;
echo "Finished, time = $waktu seconds, hasil= $hasil";
?>

JAVA

public class Java_Test

{
 public static void main(String[] args) 
 { final long mulai=System.nanoTime();
  int hasil,N;
  N=300000;
  hasil=pungsi(N);
  final long waktu=(System.nanoTime()-mulai);
  System.out.println("Finished in "+waktu+" Nano seconds, hasil="+hasil);
 }

 public static int pungsi(int N)
 { int i,j=0;
  for(i=0;i<N;i++)
  { j=i+100;
   if (j%2==0)
     {j=2;}
   while(j>(N/10))
     {j=j-10;}
  }
  return i;
 }
}

R

pungsi <- function(N) {
 j<- 0
 for (i in 1:N){
  j<- i +100
  if (j%%2==0){
   j<- 2
  }
  while(j>N/10){
   j=j-10
  }
   }
 return(i)
}
mulai <- proc.time()# Start the clock!
N<- 300000
hasil<-pungsi(N)
proc.time() - mulai # Stop the clock

C++

#include <iostream>
#include <time.h>

int pungsi(int N)
{
 int i,j=0;
 for (i = 0; i<N; i++)
 {
  j =i+100;
  if (j%2==0)
  {
   j=2;
  }
  while (j>N/10)
  {
   j=j-10;
  }
 }
 return(i);
}

int main()
{ 
 clock_t mulai=clock();
 int hasil, N=300000;
 hasil=pungsi(N);
 printf("Time taken: %.2fs, N=%d, hasil=%d\n",(double)(clock()-mulai)/CLOCKS_PER_SEC,N,hasil);
 return 0;
}

Julia

function pungsi(N::Integer)
for i=1:N
    j=i+100
    if j%2==0
        j=2
    end
    while j>N/10
        j=j-10
    end
end
end
@time pungsi(300000)
[Taufik-Sutanto]

Tidak ada komentar:

Posting Komentar

Relevant & Respectful Comments Only.