Scala的循环反应的性能非常差.为什么?

liu*_*tao 4 java performance scala

我只是在scala和java中编写了一个生产者 - 消费者演示.该演示表明Scala的性能非常差.我的代码错了吗?

Java AVG:1933534.1171935236
Scala AVG:103943.7312328648

Scala代码:

import scala.actors.Actor.actor
import scala.actors.Actor.loop
import scala.actors.Actor.react
import scala.concurrent.ops.spawn
object EventScala {

case class Event(index: Int)

def test() {
    val consumer = actor {
        var count = 0l
        val start = System.currentTimeMillis()
        loop {
            react {
                case Event(c) => count += 1
                case "End" =>
                    val end = System.currentTimeMillis()
                    println("Scala AVG:" + count * 1000.0 / (end - start))
                    exit()
            }
        }
    }
    var running = true;
    for (i <- 0 to 1) {
        {
            spawn {
                while (running) {
                    consumer ! Event(0)
                }
                consumer!"End"
            }
        }
    }
    Thread.sleep(5000)
    running = false
}

def main(args: Array[String]): Unit = {
    test
}

}
Run Code Online (Sandbox Code Playgroud)

Java代码:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class EventJava {
static BlockingQueue<Event> queue = new LinkedBlockingQueue<EventJava.Event>();
static volatile boolean running = true;
static volatile Event sentinel = new Event(0);

static class Event {
    final int index;

    public Event(int index) {
        this.index = index;
    }
}

static class Consumer implements Runnable {
    @Override
    public void run() {
        long count = 0;
        long start = System.currentTimeMillis();
        while (true) {
            try {
                Event event = queue.take();
                if (event == sentinel) {
                    long end = System.currentTimeMillis();
                    System.out.println("Java AVG:" + count * 1000.0
                            / (end - start));
                    break;
                }
                count++;
            } catch (InterruptedException e) {
            }
        }
    }
}

static class Producer implements Runnable {
    @Override
    public void run() {
        while (running) {
            queue.add(new Event(1));
        }
        queue.add(sentinel);
    }
}

static void test() throws InterruptedException {
    ExecutorService pool = Executors.newCachedThreadPool();
    pool.submit(new Consumer());
    pool.execute(new Producer());
    pool.execute(new Producer());
    Thread.sleep(5000);
    running = false;
    pool.shutdown();
}

public static void main(String[] args) throws InterruptedException {
    test();
}

}
Run Code Online (Sandbox Code Playgroud)

Dan*_*ral 6

您正在测试两个非常不同的代码.我们考虑Java,例如:

    while (true) {
Run Code Online (Sandbox Code Playgroud)

其他"演员"有机会接管线程并对自己进行一些处理吗?这个"演员"几乎占据了主线.如果你创建了100000个,你会看到JVM在竞争"演员"的压力下被粉碎,或者看到一些得到所有处理时间,而其他人则萎靡不振.

            Event event = queue.take();
            if (event == sentinel) {
Run Code Online (Sandbox Code Playgroud)

为什么要将事件从队列中取出而不检查它是否可以处理?如果无法处理,您将失去该事件.如果您将其添加回队列,它将在同一源发送的其他事件之后结束.

这些只是Scala代码执行的两件事,而Java代码则没有.

  • @ toto2不,只创建你创建的演员.但是,预计会创建许多actor,这就是`loop`和`react`之类的东西.我的观点是Scala _actors_已经准备好了,而不是示例利用它们.但无论该示例是否利用它们,所有基础设施都在那里.当然,如果将它与_without_所有基础设施进行比较,它会更慢. (2认同)