【本文已迁移到“程序员文摘” http://programmerdigest.cn/category/lajp】在当今的网络时代,我们常常见到的进程间通信方式都是socket,比如Java的EJB调用,Java和C通信,Web Service服务等。socket是最常用的通讯技术,几乎所有的系统、语言都支持,socket也是面向网络的,通信的两方可以跨越IP网络进行传输。
在本地通信中(同一台机器上的进程间通讯),socket的网络特性却成了累赘,组装解析网络报头、报文确认、CRC校验等都是针对网络的,本地通信没有必要,反而会影响传输效率。本地通信的一些传统技术,如管道、FIFO、消息队列等,没有网络功能的负担,传输速度应该高于socket,那到底高多少以至于值得在应用中替换socket技术呢,今天就来一场小测试,就System V消息队列和socket之间,做一次全面的速度比拼。
比拼场地:
本人的笔记本:赛扬1.5G 内存1.5G
系统:Ubuntu8.04 Desktop (Linux 2.6.24-24-generic)
JDK:1.6
第一回合: Java测试
先说明一下,Java并不支持System V消息队列,因此特为Java提供了JNI接口,我们使用lajp_9.09提供C源码编译的so动态连接库,lajp的下载地址和文档:http://code.google.com/p/lajp/
首先上场的是System V消息队列。
发送端程序:
001 package test;
002
003 import lajp.MsgQ;
004
005 public class TestSend
006 {
007 /** 消息队列KEY */
008 static final int IPC_KEY = 0x20021230;
009
010 static
011 {
012 //JNI
013 System.loadLibrary("lajpmsgq");
014 }
015
016 public static void main(String[] args)
017 {
018 //创建或获得现有的消息队列
019 int msqid = MsgQ.msgget(IPC_KEY);
020 //发送字节数组
021 byte[] msg = new byte[1024];
022
023 for (int i = 0; i < 1024 * 5000; i++)
024 {
025 //每次发送1204字节到消息队列,9527是消息类型
026 MsgQ.msgsnd(msqid, 9527, msg, msg.length);
027 }
028
029 System.out.println("发送结束.");
030 }
031 }
接收端程序:
001 package test;
002
003 import lajp.MsgQ;
004
005 public class TestRcv
006 {
007 /** 消息队列KEY */
008 static final int IPC_KEY = 0x20021230;
009
010 static
011 {
012 //JNI
013 System.loadLibrary("lajpmsgq");
014 }
015
016 public static void main(String[] args)
017 {
018 //创建或获得现有的消息队列
019 int msqid = MsgQ.msgget(IPC_KEY);
020 //接收缓冲区
021 byte[] msg = new byte[1024];
022
023 long start = System.currentTimeMillis(); //开始时间
024
025 for (int i = 0; i < 1024 * 5000; i++)
026 {
027 //每次从消息队列中接收消息类型为9527的消息,接收1204字节
028 MsgQ.msgrcv(msqid, msg, msg.length, 9527);
029 }
030
031 long end = System.currentTimeMillis(); //结束时间
032 System.out.println("用时:" + (end - start) + "毫秒");
033 }
034 }
程序很简单,需要说明的是三个JNI方法调用:
msgget()方法: System V消息队列的技术要求,含义是通过一个指定的KEY获得消息队列标识符。
msgsnd()方法: 发送。
msgrcv()方法: 接收。
发送方进行了(1024 * 5000)次发送,每次发送1024字节数据,接收方进行了(1024 * 5000)次接收,每次接收1024字节,共计发送接收5G数据。测试时先启动TestSend程序,再启动TestRcv程序,共进行5轮次测试,测试结果如下:
用时:29846毫秒
用时:29591毫秒
用时:29935毫秒
用时:29730毫秒
用时:29468毫秒
平均速度:29714毫秒
用top命令监控测试期间的CPU、内存的使用:
接下来上场的是socket。
发送端程序:
001 import java.io.IOException;
002 import java.io.OutputStream;
003 import java.net.Socket;
004
005 public class Soc