การเปรียบเทียบประสิทธิภาพเวบระหว่าง PHP, D lang และ Go lang
Mon, 13 April 2015 php golang dlang

ช่วงนี้อยู่ในช่วงพัฒนาระบบใหม่ ๆ จึงอยากจะหาภาษาใหม่ ๆ ที่มีประสิทธิภาพสูง ๆ รองรับงานใหญ่ ๆ ได้ จึงได้ทำการทดลองสร้างเวบที่หาค่า Fibonucci(20) แล้วแสดงผลออกมา และวัดประสิทธิภาพในการทำงานออกมา โดยผมได้ทดลองกับภาษายอดนิยม PHP กับภาษาเกิดใหม่ที่น่าสนใจคือ ภาษา D และภาษา Go โดยมีการทดลองดังนี้ครับ

1. การเตรียมเครื่องมือสำหรับการทดลอง

การทดลองผมจะทดลองบนเครื่อง PC ส่วนตัว โดยจะมี CPU Intel® Core™ i3-2100 CPU @ 3.10GHz ซึ่งมีขนาด 4 Core แบบ Logical และหน่วยความจำขนาด 8GB ทำงานบนระบบปฏิบัติการ Archlinux แบบ 64 Bits และใช้โปรแกรม wrk สำหรับวัดการตอบสนอง โดยมีผลลัพธ์เป็น Request per Seconds ซึ่งการวัดจะแบ่งวัดเป็น 3 รูปแบบ คือ 100 Concurrent, 300 Concurrent และ 1000 Concurrent โดยตัวอย่างคำสั่งที่ใช้ทดสอบดังนี้ครับ

$ wrk -c 100 -d 10 http://localhost:9700/

2. การเตรียมการสำหรับภาษา PHP

สำหรับภาษา PHP ผมใช้ Web Server Front End เป็น Nginx และ ใช้ PHP-FPM ซึ่งเชื่อมต่อกันผ่าน FastCGI และเป็นภาษา PHP 5.6.7 โดยจะทำการทดลอง 2 กรณีคือ กรณีที่มี 1 Worker และ 4 Workers โดยตัวอย่าง Code ดังนี้

File : fib.php

<?php
function fib($n) {
    if($n < 2) return $n;
    return fib($n-1)+fib($n-2);
}

echo fib(20);
?>

3. การเตรียมการสำหรับภาษา D

สำหรับภาษา D ผมได้ใช้ Vibe.d เป็น Web Framework โดยจะทำการทดลอง 2 กรณีคือ กรณีที่มี 1 Thread และ 4 Theards โดยตัวอย่าง Code กรณี 1 Thread ดังนี้

File : one.d

import vibe.d;
import std.conv;

shared static this()
{
    auto settings = new HTTPServerSettings;
    settings.port = 9700;
    settings.bindAddresses = ["::1", "127.0.0.1"];
    listenHTTP(settings, &hello);

    logInfo("Please open http://127.0.0.1:9700/ in your browser.");
}

int fib(int n)
{
    if(n < 2) return n;
    return fib(n-1)+fib(n-2);
}

void hello(HTTPServerRequest req, HTTPServerResponse res)
{
    string d = text(fib(20));
    res.writeBody(d);
}

ตัวอย่าง Code กรณี 4 Thread ดังนี้

File : multi.d

import vibe.d;
import std.conv;

shared static this()
{
    auto settings = new HTTPServerSettings;
    settings.port = 9700;
    settings.bindAddresses = ["::1", "127.0.0.1"];
    settings.options |= HTTPServerOption.distribute;
    listenHTTP(settings, &hello);

    logInfo("Please open http://127.0.0.1:9700/ in your browser.");
}

int fib(int n)
{
    if(n < 2) return n;
    return fib(n-1)+fib(n-2);
}

void hello(HTTPServerRequest req, HTTPServerResponse res)
{
    string d = text(fib(20));
    res.writeBody(d);
}

4. การเตรียมการสำหรับภาษา Go

สำหรับภาษา Go ผมได้ใช้ Package “net/http” ซึ่งเป็น Standard Library มาทำการทดลอง โดยจะทำการทดลอง 2 กรณีคือ กรณีที่มี 1 Thread และ 4 Theards โดยตัวอย่าง Code กรณี 1 Thread ดังนี้

File : one.go

package main

import (
    "net/http"
    "fmt"
)

func fib(n int) int {
    if n < 2 {
        return n
    }
    return fib(n-1)+fib(n-2)
}

func serve(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%d", fib(20))
}

func main() {
    http.HandleFunc("/", serve)
    http.ListenAndServe(":9700", nil)
}

ตัวอย่าง Code กรณี 4 Thread ดังนี้

File : multi.go

package main

import (
    "net/http"
    "fmt"
    "runtime"
)

func fib(n int) int {
    if n < 2 {
        return n
    }
    return fib(n-1)+fib(n-2)
}

func serve(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%d", fib(20))
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    http.HandleFunc("/", serve)
    http.ListenAndServe(":9700", nil)
}

5. ผลการทดลอง

จากการทดลอง ได้นำมาสร้างเป็นกราฟแสดงผลดังนี้ compare จากกราฟจะเห็นว่าประสิทธิภาพของภาษารุ่นใหม่ คือ D และ Go ค่อนข้างน่าประทับใจ แต่ดูเหมือนภาษา Go จะเหนือกว่าเล็กน้อย ในส่วนภาษา PHP น่าประหลาดใจ คือ ประสิทธิภาพที่ทดลองกรณี Concurrent ที่ 300 ขึ้นไป สามารถขึ้นไปได้สูงถึง 16000 Request per Seconds ซึ่งในขณะที่ Concurrent ที่ 100 ทำได้เพียง 300 สำหรับ 1 Worker และ 700 สำหรับ 4 Workers ซึ่งคาดว่าน่าจะเกิดจากการใช้ Caching เข้าช่วย สำหรับภาษาเกิดใหม่ ยังมีอีก 2 ภาษาที่น่าสนใจมาก ๆ คือ ภาษา Rust และ ภาษา Nim ซึ่งผมไม่ได้ทำการทดลอง เพราะเป็นภาษาที่ยังไม่เกิด version 1.00 เลย จึงทำให้ตัวภาษาและ Standard Library ยังไม่นิ่ง ซึ่งผมก็ Compile เวบทั้งสองภาษายังไม่ผ่านเลย เนื่องจากการเปลี่ยนแปลงที่ยังพัฒนาอยู่ แต่ก็น่าสนใจและติดตามอย่างยิ่ง สำหรับผมเห็นแบบนี้แล้ว คงต้องวิ่งไปหา Go ก่อนละครับ :)

comments powered by Disqus