2016-11-24 59 views
0

我有如下代码:提高斯卡拉列表查询

for (user <- allValidationTransaction){ 
    val u_t = allTrainTransaction.slice(0, allTrainTransaction. 
    indexWhere(_.Transaction_ID == user.Transaction_ID)). 
      filter(_.CARD_ID == user.CARD_ID) 
} 

我该如何提高呢?它很慢。

+2

使用'Vector'而不是'List'会有所改进。 – jwvh

+0

名单有多大?你可以使用平行集合吗? – Pavel

+0

我的清单有600,000行。 – Nasir

回答

0

这将根据核心数量快四倍或更多倍。使用30000行两个2.5Ghz核心的速度要快五倍。请注意,List越多,降级越多。

val allValidationTransaction: IndexedSeq[tranx] = IndexedSeq.fill(30000)(random) 
val allTrainTransaction : IndexedSeq[userx] = IndexedSeq.fill(30000)(random_u) 

for (user <- allValidationTransaction){ 
    val u_t = allTrainTransaction.par.slice(0, allTrainTransaction.par. 
    indexWhere(_.Transaction_ID == user.Transaction_ID)). 
     filter(_.CARD_ID == user.CARD_ID) 
} 

检查CPU使用情况以观察par集合如何分配计算。

+0

我不知道为什么,但它很慢。 :( – Nasir

+0

需要多少时间,也许在60万行中,有必要采取其他策略,结构如何,你看过%CPU吗? – EmiCareOfCell44

+0

谢谢你的回应,我测试了它。 '.par'没有'.par'比'IndexedSeq'快于'.par'而没有'.par'。 – Nasir

0

如果您的收藏 - allValidationTransaction和allTrainTransaction无法随机访问,您的代码效率不高。 例如,slice和indexWhere列表不是常量操作。 请参阅http://www.scala-lang.org/api/current/scala/collection/immutable/List.html

时间:列表有O(1)prepend和head/tail访问。大多数其他 操作都是O(n)列表中元素的数量。这个 包括基于索引的元素查找,长度,追加和逆向。

此外,如果您的代码遍历每个用户3次allTrainTransaction集合。

  1. 要找到具有相同的事务ID
  2. 切片(如果它不是随机访问)
  3. 要过滤如果你改变你的代码具有相同的卡ID

指数程序风格,你可以获得性能优势。

以下是更新的答案。代码未经测试。但它似乎工作。

@tailrec 
def helper[T](acc: Vector[T], trainTransactions: List[T], validTransaction: T): Vector[T] = 
    trainTransactions match { 
    case trainTransaction :: otherTrainTransactions if trainTransaction.Transaction_ID == validTransaction.Transaction_ID => 
     acc 

    case trainTransaction :: otherTrainTransactions if trainTransaction.CARD_ID == validTransaction.CARD_ID => 
     helper(acc :+ trainTransaction, otherTrainTransactions, validTransaction) 

    case trainTransaction :: otherTrainTransactions => 
     helper(acc, otherTrainTransactions, validTransaction) 

    case Nil => Nil 
    } 

allValidationTransaction.foldLeft(Vector.empty) { 
    case (acc, validationTransaction) => 
    acC++ helper(acc, allTrainTransactions, validationTransaction) 
} 
+0

你是对的,但函数式编程非常有趣,我想知道如何改进查询? – Nasir