锁定老帖子 主题:thrift和erl_nif效率上的比较
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-01-10
thrift是通用型的,可以完成多种编程语言之间的交互,erl_nif是专用型的,主要完成Erlang和C语言之间的交互。thrift可以完成远程节点之间的交互,但是erl_nif只能完成本地的交互。 正因为thrift完成的是远程节点之间的交互,(thrift在facebook设计指出,主要的目的就是完成facebook数据中心中不同编程语言之间的交互)它在处理本地交互时,同样会看作是远程的方式进行工作;erl_nif的运行中,省去了远程节点的通信。所以,thrift的运行性能不如erl_nif的运行性能。 但是,如果要完成远程节点之间的语言交互,使用erl_nif,也不见得有多大优势。首先,远程之间之间的交互,必然要使用通信,就算是用原生的socket进行通信,性能上面而言,优势也甚微。但是,如果使用这种方式,开发效率就大大的降低了。 所以,如果在本地要完成C语言和Erlang语言之间的交互的话,使用erl_nif是没有错的(使用指南,可以google一下),但是如果要完成远程节点之间多编程语言的交互,选择thrift在一定程度上,还是要比erl_nif好。
贴出thrift完成CPP+Erlang计算100W以内prime的代码 CPP端的代码
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include <stdio.h> #include <iostream> #include <vector> #include <unistd.h> #include <math.h> #include <sys/time.h> #include <protocol/TBinaryProtocol.h> #include <transport/TSocket.h> #include <transport/TTransportUtils.h> #include "../gen-cpp/Sendinfo.h" using namespace std; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace cpp2erl; using namespace shared; using namespace boost; bool isPrime(int i) { int j; int t = sqrt(i) + 1; for(j = 2; j <= t; ++j) { if(i % j == 0) return false; } return true; } int main(int argc, char** argv) { shared_ptr<TTransport> socket(new TSocket("localhost", 9909)); shared_ptr<TTransport> transport(new TBufferedTransport(socket)); shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); SendinfoClient client(protocol); timeval end,start; try { gettimeofday(&start,NULL); vector<int> Mylist; for(int i=0;i<1000000;i++) { if(isPrime(i)) { Mylist.push_back(i); } } gettimeofday(&end,NULL); transport->open(); client.sendinfo(Mylist); long timeuse = 1000000*(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec; cout<<timeuse<<endl; transport->close(); } catch (TException &tx) { printf("ERROR: %s\n", tx.what()); } }
Erlang端的代码
%% %% Licensed to the Apache Software Foundation (ASF) under one %% or more contributor license agreements. See the NOTICE file %% distributed with this work for additional information %% regarding copyright ownership. The ASF licenses this file %% to you under the Apache License, Version 2.0 (the %% "License"); you may not use this file except in compliance %% with the License. You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, %% software distributed under the License is distributed on an %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY %% KIND, either express or implied. See the License for the %% specific language governing permissions and limitations %% under the License. %% -module(server). -include("sendinfo_thrift.hrl"). -export([start/0,start/1,handle_function/2,stop/1,ping/0,zip/0,debug/2,sendinfo/1]). debug(Format, Data) -> error_logger:info_msg(Format, Data). ping() -> debug("ping()",[]), ok. sendinfo(Mylist) -> {Nodename} = {Mylist}, debug("~w~n", [Nodename]). zip() -> debug("zip", []), ok. %% start() -> start(9909). start(Port) -> Handler = ?MODULE, thrift_socket_server:start([{handler, Handler}, {service, sendinfo_thrift}, {port, Port}, {name, tutorial_server}]). stop(Server) -> thrift_socket_server:stop(Server). handle_function(Function, Args) when is_atom(Function), is_tuple(Args) -> case apply(?MODULE, Function, tuple_to_list(Args)) of ok -> ok; Reply -> {reply, Reply} end. 测试: 1、测试thrift的额外消耗,修改CPP代码
gettimeofday(&start,NULL); transport->open(); transport->close(); gettimeofday(&end,NULL); long timeuse = 1000000*(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec; cout<<timeuse<<endl;
transport open动作和close动作,需要消耗的时间在2462微秒左右(测试十八个数据,取其平均值) 可以看出,因使用thrift而产生的额外消耗,只有0.2462毫秒,与使用thrift带来的开发效率的提高,可以忽略不计。 2、thrift传输产生的消耗,同样需要修改下CPP代码
gettimeofday(&start,NULL); client.sendinfo(Mylist); gettimeofday(&end,NULL); long timeuse = 1000000*(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec; cout<<timeuse<<endl; 测试thrift完成传输需要消耗的时间,1545771微秒,也就是1.5秒左右 3、测试整个过程需要的时间 测试从判断prime到传给erlang 所需要的时间,1876668微秒,1900毫秒左右,和erl_nif完成该工作,相差了1秒左右,(参见:http://www.iteye.com/topic/534368)
总结: 虽然,thrift和erl_nif运行效率相比,确实不行,但是,thrift完成的多语言交互,可以轻松不熟到远程节点,不仅如此,开发效率还要比erl_nif稍胜一筹(个人观点)。 君子性非异也,善假于物也。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 2581 次