Vinova tuyển lập trình viên Mobile & Web ở Hà Nội, lương $300-1000

Article: Erlang vs. Ruby: So sánh tốc độ truyền thông điệp giữa các process 1097

ngocdaothanh.myopenid.com 172
Updated over 3 years ago

RPC có một số hạn chế. Truyền thông điệp là cách tốt hơn, đã được Erlang chứng minh hiệu quả. Bài viết này thử nghiệm và so sánh một số cách thực hiện của của Erlang và Ruby.

Môi trường thử nghiệm

Ta viết chương trình echo đơn giản. Process client gửi khoảng 100 byte (vì cần serialize và deserialize, nên không thể xác định chính xác) đến process server. Server khi nhận được thì gửi trả lại ngay cho client.

Về nguyên tắc, 2 process này có thể nằm trên 2 máy khác nhau. Để đơn giản, ta chỉ chạy trên 1 máy:

  • MacBook Pro 2.4 GHz Intel Core 2 Duo
  • Memory 2 GB 667 MHz DDR2 SDRAM
  • Mac OS X Leopard 10.5.5
  • Erlang 5.6.3
  • Ruby 1.8.7 và 1.9.0

Erlang - !

Trước tiên ta dùng cách đơn giản nhất là cứ thế mà lôi process ID ra mà gọi.

Server:

-module(server).

-export([start_link/0]).

start_link() ->
global:register_name(server, self()),
loop().

loop() ->
receive
{Data, Pid} ->
Pid ! Data,
loop();
_Any ->
loop()
end.

Client:

-module(client).

-export([test/1]).

test(N) ->
T1 = now(),
Data = build_data(100, <<>>),
call(Data, N, T1, N).

build_data(0, Acc) ->
Acc;
build_data(Len, Acc) ->
Byte = random:uniform(256) - 1,
build_data(Len - 1, <<Byte, Acc/binary>>).

call(_Data, N, T1, 0) ->
{_, Sec2, Micro2} = now(),
{_, Sec1, Micro1} = T1,
Dt = (Sec2 + Micro2/1000000) - (Sec1 + Micro1/1000000),
io:format("N = ~p, Dt = ~p (~p)~n", [N, Dt, N/Dt]);
call(Data, N, T1, Current) ->
global:send(server, {Data, self()}),
receive
_Any ->
ok
end,
call(Data, N, T1, Current - 1).

Cách chạy:

  • Chạy server node: erl -sname server@localhost -setcookie Test
  • Chạy client node: erl -sname client@localhost -setcookie Test
  • Từ client node thông đến server node: net_adm:ping(server@localhost)
  • Ping thử 10^5 lần: client:test(100000).

Kết quả cho thấy tốc độ đạt khoảng 8500 lần/s.

Erlang - gen_server

Khi viết chương trình một cách nghiêm túc, không thể không dùng OTP.

Server:

-module(server).

-behaviour(gen_server).

-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).

-record(state, {}).

start_link() ->
gen_server:start_link({global, server}, ?MODULE, [], []).

init([]) ->
{ok, #state{}}.

handle_call(Request, _From, State) ->
Reply = Request,
{reply, Reply, State}.

handle_cast(_Msg, State) ->
{noreply, State}.

handle_info(_Info, State) ->
{noreply, State}.

terminate(_Reason, _State) ->
ok.

code_change(_OldVsn, State, _Extra) ->
{ok, State}.

Client:

Gần giống như trên, chỉ cần sửa đoạn

call(Data, N, T1, Current) ->
global:send(server, {Data, self()}),
receive
_Any ->
ok
end,
call(Data, N, T1, Current - 1).

thành

call(Data, N, T1, Current) ->
gen_server:call({global, server}, Data),
call(Data, N, T1, Current - 1).

Cách chạy như cũ, kết quả cho thấy tốc độ đạt khoảng 5000-6000 lần/s. Khi đổi gen_server:call thành gen_server:cast, tốc độ tăng lên khoảng 10 lần (hiển nhiên{#emotions_dlg.laughing}).

Ruby  - revent

Ruby có sẵn DRuby, nhưng nó là RPC. Ta dùng revent, thư viện dựa trên thư viện cực nổi tiếng EventMachine. Thư viện này đã có sẵn ví dụ echo, chỉ việc chạy, khoẻ{#emotions_dlg.tongue_out}.

Kết quả cho thấy tốc độ đạt khoảng 7000 và 11500 lần/s lần với lần lượt Ruby 1.8.7 và 1.9.0.

Kết luận

Đồ thị ở đầu bài tạo nhờ trang Create A Graph.

Ruby 1.9 quả đáng mặt anh hùng{#emotions_dlg.cool}. Nếu chỉ xét tốc độ thì Ruby nhỉnh hơn. Nhưng nếu xét thêm nhiều yếu tố khác như độ dễ viết, scalability thì Erlang nhỉnh hơn.

Ghi chú

Thử nghiệm sơ trên môi trường:

  • Intel(R) Xeon(TM) CPU 2.80GHz
  • Memory 1 GB
  • Ubuntu 8.04
  • Erlang 5.5.5 HiPE
  • Ruby 1.8.6 và 1.9.0

cho kết quả:

  • Erlang - !: 11000
  • Erlang - gen_server: 7500
  • Ruby (cả 2!): 3000 (Ruby 1.9 sau vài lần chạy thì bị error, nghĩa là chưa ổn định)

Ngoài ra, EventMachine có đối thủ nặng kí là rev. Thử chạy rev với Ruby 1.9 trên Leopard ở trên cho kết quả 15000.

Comments

nhudinhthuan.myopenid.com 6
over 3 years ago

Không hiểu sao những người làm ruby thích vs với những language hay platform khác thay vì support cộng đồng.

Trên cntt.tv, thi thoảng lại có bài ruby vs xxx gì đó. Doibuon nghĩ tính support cộng đồng cùng những tài liệu trợ giúp sẽ thúc đẩy người ta tiếp cận và trung thành hơn là cứ vs này nọ.

Xin hỏi các bác một chút, doibuon đang phát triển một hệ thống mà web chỉ là một phần rất nhỏ (đến nỗi không cần dùng đến web server hay bất cứ web framework) nào khác thì một language như ruby có thể support được.

Chẳng hạn:

 - Một data struceture đủ mạnh và nhanh.

- Một concurrent framework khá tốt.

- Viết một webserver nhẹ và đơn giản.

- GUI for desktop, tương tác với resource của os.

- Các hỗ trợ về performance cho các tính toán lớn kiểu như các giải pháp semantic.

- Giải pháp index, database (tự xây dựng một database chứ không dùng mấy cái như oracle, mysql,...), kiểm soát io,...

- Khả năng mở rộng trên các platform không phải computer như mobile, tv,...

...

Liệu bản thân ruby có thể đảm bảo?

 

ngocdaothanh.myopenid.com 172
Updated over 3 years ago

Nếu doibuon không thích từ vs thì dùng từ so sánh hoặc đối chiếu vậy. Khi thấy cái gì đó lạ lẫm, thì đối chiếu nó với kinh nghiệm có sẵn là phản xạ rất tự nhiên. doibuon đọc đoạn mở bài bài ErlyWeb vs. Ruby on Rails EC2 Performance Showdown xem. Học dựa trên so sánh là cách học hiệu quả, cho phép tận dụng (và đào sâu) kiến thức đã biết.

Về hệ thống doibuon hỏi, nếu không dùng 1 thứ được thì kết hợp nhiều thứ lại chứ có gì. Tuy nhiên để chọn được liều lượng thích hợp của mỗi thành phần, cần so sánh đối chiếu, thử nghiệm phải không? Chỗ tôi làm có tay kì cựu gần như cả ngày chỉ ngồi thử nghiệm hết framework này đến thư viện kia để viết tổng kết đánh giá.

You must login to be able to comment

Uploaded files
Name Size Uploader Time
graph.png 11.2 KB
ngocdaothanh.myopenid.com 172
over 2 years ago

You must login to be able to upload

Nhà tài trợ:

Mọi người đều tự do viết bài, sửa bài của người khác, và bình luận ở trang web này. Bạn muốn chủ động tạo bài mới để chia sẻ kinh nghiệm với mọi người? Xin click link ở dưới.

Create new content