使用 Scala foreach 处理 CQEngine ResultSet 非常慢



我正在尝试使用 Scala 的 foreach 处理 CQEngine 的 ResultSet,但结果非常慢。

以下是我正在尝试执行的操作的片段

import collection.JavaConversions._
val query = existIn(myOtherCollection, REFERENCE, REFERENCE)
val resultSet = myIndexCollection.retrieve(query)
resultSet.foreach(r =>{
    //do something here
})

不知何故,.foreach 方法非常慢。我尝试通过放置 SimonMonitor 并使用 while(resultSet.hasNext) 更改 .foreach 进行调试,令人惊讶的是,每次调用 hasNext 方法大约需要 1-2 秒。这是非常缓慢的。

我尝试使用Java创建相同的版本,并且Java版本非常快。

请帮忙

我无法用下面的测试代码重现您的问题。您可以在您的系统上试用它并让我知道它是如何运行的吗?

(取消注释第 38 行,garages.addIndex(HashIndex.onAttribute(Garage.BRANDS_SERVICED)),使 Scala 和 Java 迭代器都运行得非常快......

第一个输出(以毫秒为单位的时间):

Done adding data
Done adding index
============== Scala ============== 
Car{carId=4, name='BMW M3', description='2013 model', features=[radio, convertible]}
Time : 3 seconds
Car{carId=1, name='Ford Focus', description='great condition, low mileage', features=[spare tyre, sunroof]}
Time : 1 seconds
Car{carId=2, name='Ford Taurus', description='dirty and unreliable, flat tyre', features=[spare tyre, radio]}
Time : 2 seconds
============== Java ============== 
Car{carId=4, name='BMW M3', description='2013 model', features=[radio, convertible]}
Time : 3 seconds
Car{carId=1, name='Ford Focus', description='great condition, low mileage', features=[spare tyre, sunroof]}
Time : 1 seconds
Car{carId=2, name='Ford Taurus', description='dirty and unreliable, flat tyre', features=[spare tyre, radio]}
Time : 2 seconds

代码如下:

import collection.JavaConversions._
import com.googlecode.cqengine.query.QueryFactory._
import com.googlecode.cqengine.CQEngine;
import com.googlecode.cqengine.index.hash._;
import com.googlecode.cqengine.IndexedCollection;
import com.googlecode.cqengine.query.Query;
import java.util.Arrays.asList;
object CQTest {
  def main(args: Array[String]) {
    val cars: IndexedCollection[Car] = CQEngine.newInstance();
    cars.add(new Car(1, "Ford Focus", "great condition, low mileage", asList("spare tyre", "sunroof")));
    cars.add(new Car(2, "Ford Taurus", "dirty and unreliable, flat tyre", asList("spare tyre", "radio")));
    cars.add(new Car(3, "Honda Civic", "has a flat tyre and high mileage", asList("radio")));
    cars.add(new Car(4, "BMW M3", "2013 model", asList("radio", "convertible")));
    // add cruft to try and slow down CQE
    for (i <- 1 to 10000) {
      cars.add(new Car(i, "BMW2014_" + i, "2014 model", asList("radio", "convertible")))
    }
    // Create an indexed collection of garages...
    val garages: IndexedCollection[Garage] = CQEngine.newInstance();
    garages.add(new Garage(1, "Joe's garage", "London", asList("Ford Focus", "Honda Civic")));
    garages.add(new Garage(2, "Jane's garage", "Dublin", asList("BMW M3")));
    garages.add(new Garage(3, "John's garage", "Dublin", asList("Ford Focus", "Ford Taurus")));
    garages.add(new Garage(4, "Jill's garage", "Dublin", asList("Ford Focus")));
    // add cruft to try and slow down CQE
    for (i <- 1 to 10000) {
      garages.add(new Garage(i, "Jill's garage", "Dublin", asList("DONT_MATCH_CARS_BMW2014_" + i)))
    }
    println("Done adding data")
    // cars.addIndex(HashIndex.onAttribute(Car.NAME));
    // garages.addIndex(HashIndex.onAttribute(Garage.BRANDS_SERVICED));
    println("Done adding index")
    val query = existsIn(garages, Car.NAME, Garage.BRANDS_SERVICED, equal(Garage.LOCATION, "Dublin"))
    val resultSet = cars.retrieve(query)
    var previous = System.currentTimeMillis()
    println("============== Scala ============== ")
    // Scala version
    resultSet.foreach(r => {
      println(r);
      val t = (System.currentTimeMillis() - previous)
      System.out.println("Time : " + t / 1000 + " seconds")
      previous = System.currentTimeMillis()
    })
    println("============== Java ============== ")
    previous = System.currentTimeMillis()
    // Java version
    val i: java.util.Iterator[Car] = resultSet.iterator()
    while (i.hasNext) {
      val r = i.next()
      println(r);
      val t = (System.currentTimeMillis() - previous)
      System.out.println("Time : " + t / 1000  + " seconds")
      previous = System.currentTimeMillis()
    }
  }
}

最新更新