Simple Scala actor Vs java Thread Vs Kilim Test

In this blog,I'll test the coroutine supported on jvm,now famous is scala actor & kilim,this blog show the program reliazed with scala actor/kilim/java,let's compare these three program performance.

Test scene:
1.start cpu+1 threads;
2.these threads notify processor,repeat (cpu+1)*100 times,every time notify sleep random(5) ms;
3.processor asynchronous handle the message,the handler process is create a List(1000),and add element to this list,then sleep random(2) ms,repeat the process 100 times,then finish the processor.

Test Machine I: 2 core CPU(Intel(R) Xeon(R) CPU  E5410  @ 2.33GHz) 1.5G memory
Test Env: JDK 1.6.0_07、linux kernel 2.6.9
Execute result:
1. java version: 8397ms    cpu us: about 84%  sy: about 8% 
2. scala version: 12403ms   cpu us: about 70%  sy: about 13%
3. kilim version: 10959ms   cpu us: about 70%  sy: about 14%

Test Machine II: 8 core CPU(Intel(R) Xeon(R) CPU  E5410  @ 2.33GHz) 4G memory
Test Env: JDK 1.6.0_14、linux kernel 2.6.9
Execute result:
1. java version: 36797ms    cpu us: about 80%  sy: about 3% 
2. scala version: 19722ms   cpu us: about 70%  sy: about 1.5%
3. kilim version: 16008ms   cpu us: about 85%  sy: about 1.8%

Execute summary:
When cpu core and thread adds, scala & kilim performance will be better than java version, It show scala & kilim can use multicore cpu more effectivly, kilim performance sees better than scala in this scene.

If you have some tunning suggest,pls let me know,thks.

java version code:
public class MicroBenchmark {

    
private static final int processorCount=Runtime.getRuntime().availableProcessors()+1;
    
    
private static Processor processor=new Processor();
    
    
private static CountDownLatch latch=null;
    
    
private static Random random=new Random();
    
    
private static int executeTimes=processorCount*100;
    
    
public static void main(String[] args) throws Exception{
        
long beginTime=System.currentTimeMillis();
        latch
=new CountDownLatch(executeTimes*processorCount);
        
for (int j = 0; j < processorCount; j++) {
            
new Thread(new NotifyProcessorTask()).start();
        }
        latch.await();
        
long endTime=System.currentTimeMillis();
        System.out.println(
"execute time: "+(endTime-beginTime)+" ms");
    }
    
    
static class NotifyProcessorTask implements Runnable{

        
public void run() {
            
for (int i = 0; i < executeTimes; i++) {
                processor.messageReceived(latch);
                
try {
                    Thread.sleep(random.nextInt(
5));
                } 
                
catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }

}

public class Processor {

    
private static final int maxThread=(Runtime.getRuntime().availableProcessors()+1)*100;
    
    
private static ThreadPoolExecutor executor=null;
    
    
private Random random=new Random();
    
    
public Processor(){
        executor
=new ThreadPoolExecutor(10,maxThread,5,TimeUnit.SECONDS,new SynchronousQueue<Runnable>(),new ThreadPoolExecutor.AbortPolicy());
    }
    
    
public void messageReceived(final CountDownLatch latch){
        Runnable task
=new Runnable(){

            
public void run() {
                
try {
                    handle();
                } 
                
catch (Exception e) {
                    e.printStackTrace();
                }
                latch.countDown();
            }
            
        };
        executor.execute(task);
    }
    
    
private void handle() throws Exception{
        
int counter=0;
        
while(counter<100){
            List
<String> list=new ArrayList<String>();
            
for (int i = 0; i < 1000; i++) {
                list.add(String.valueOf(i));
            }
            counter
++;
            Thread.sleep(random.nextInt(
2));
        }
    }
    
}

scala version code:
object MicroBenchmark {
  
  val processorCount
=Runtime.getRuntime.availableProcessors+1
  val executeTimes
=processorCount*100
  
  def main(args : Array[String]) : Unit 
= {
    val beginTime
=System.currentTimeMillis
    val latchCount
=executeTimes*processorCount
    var latch
=new CountDownLatch(latchCount)
    var i
=0
    
while(i<processorCount){
      
new Thread(new NotifyProcessorTask(latch)).start
      i
+=1
    }
    latch.await()
    val endTime
=System.currentTimeMillis;
    println(
"execute time: "+(endTime-beginTime)+"ms")
    exit
  }
}

class NotifyProcessorTask(latch:CountDownLatch) extends Runnable{
    val executeTimes
=(Runtime.getRuntime.availableProcessors+1)*100
    val random
=new Random
    val actor
=new Processor
    
    def run() {
      var i
=0
      actor.start
      
while(i < executeTimes){
        actor 
! TaskMessage.TaskExecuted(latch,0)    
        i
+=1
        Thread.sleep(random.nextInt(
5))
      }
    }
}

abstract sealed class TaskMessage
object TaskMessage {
  
case class TaskExecuted(latch: CountDownLatch, counter:Int) extends TaskMessage
}

class Processor extends Actor{

  var random
=new Random
  
  def act(){
    loop {
      react {
        
case TaskMessage.TaskExecuted(latch,counter) => handle(latch,counter)
      }
    }
  }
  
  def handle(latch: CountDownLatch,counter: Int){
    val list
=new Array[String](1000)
    var i
=0
    
for(i<-0 to 999){
      list(i)
=i.toString
    }
    var selfCounter
=counter;
    
if(selfCounter<99){
        selfCounter
+=1
        
new Sleeper(random.nextInt(2),this,selfCounter,latch).start
    }
    
else{
        latch.countDown()
    }
  }
  
}

class Sleeper(time: Long, origin:Actor, counter:Int, latch:CountDownLatch) extends Actor {
    def act() {
        reactWithin(time) {
            
case TIMEOUT =>
                 origin 
! TaskMessage.TaskExecuted(latch,counter)
          }
    }
}

kilim code version:
public class MicroBenchmark {

    
private static final int processorCount=Runtime.getRuntime().availableProcessors()+1;
    
    
private static CountDownLatch latch=null;
    
    
private static Random random=new Random();
    
    
private static int executeTimes=processorCount*100;
    
    
public static void main(String[] args) throws Exception{
        
long beginTime=System.currentTimeMillis();
        latch
=new CountDownLatch(executeTimes*processorCount);
        
for (int j = 0; j < processorCount; j++) {
            
new Thread(new NotifyProcessorTask()).start();
        }
        latch.await();
        
long endTime=System.currentTimeMillis();
        System.out.println(
"execute time: "+(endTime-beginTime)+" ms");
        System.exit(
0);
    }
    
    
static class NotifyProcessorTask implements Runnable{

        
public void run() {
            String threadName
=Thread.currentThread().getName();
            
for (int i = 0; i < executeTimes; i++) {
                Mailbox
<String> messages=new Mailbox<String>();
                
new Processor(messages,latch).start();
                messages.putnb(threadName
+String.valueOf(i));
                
try {
                    Thread.sleep(random.nextInt(
5));
                } 
                
catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }

}

public class Processor extends Task{
    
    
private Random random=new Random();
    
    
private Mailbox<String> messages;
    
    
private CountDownLatch latch;
    
    
public Processor(Mailbox<String> messages,CountDownLatch latch){
        
this.messages=messages;
        
this.latch=latch;
    }
    
    
public void execute() throws Pausable, Exception {
        messages.get();
        
int counter=0;
        
while(counter<100){
            List
<String> list=new ArrayList<String>();
            
for (int i = 0; i < 1000; i++) {
                list.add(String.valueOf(i));
            }
            counter
++;
            Task.sleep(random.nextInt(
2));
        }
        latch.countDown();
        Task.exit(
0);
    }
    
}

posted on 2009-11-25 17:23 BlueDavy 阅读(7525) 评论(7)  编辑  收藏 所属分类: Java

评论

# re: 简单的scala actor和java多线程处理的测试 2009-11-26 10:10 lazycai

kersterl? kestrel?
文章不错!  回复  更多评论   

# re: 简单的scala actor和java多线程处理的测试 2009-11-26 10:15 xz

java下其实也有基于actor模型的实现,是不是也可以对比下?
如:
http://www.infoq.com/cn/news/2008/07/kilim-message-passing-in-java  回复  更多评论   

# re: 简单的scala actor和java多线程处理的测试 2009-11-26 10:20 lazycai

顺便,邀请一下:https://groups.google.com/group/scalacn  回复  更多评论   

# re: 简单的scala actor和java多线程处理的测试 2009-11-26 10:25 BlueDavy

@xz
恩,好,之后折腾下。  回复  更多评论   

# re: 简单的scala actor和java多线程处理的测试 2009-11-26 11:08 dd_macle

真是长江后浪推前浪  回复  更多评论   

# re: 简单的scala actor和java多线程处理的测试 2009-11-26 11:43 BlueDavy

@dd_macle
:),新的语言更强调充分发挥多核的优势,提升语言本身在并行、并发方面的支持,尽管java也在提升,但毕竟java已经庞大了,所以必然要迟缓一些。  回复  更多评论   

# re: Simple Scala actor Vs java Thread Vs Kilim Test 2009-11-26 16:45 BlueDavy

@xz
呵呵,增加了kilim的测试,性能表现竟然超过了scala.  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告

 









feedsky
抓虾
google reader
鲜果

导航

<2009年11月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

统计

随笔分类

随笔档案

文章档案

Blogger's

搜索

最新评论

阅读排行榜

评论排行榜