我有一个文本文件,其结构为第一行包含制表符分隔的键,而所有后续行均包含这些键的制表符分隔的值。因此,可以使用第一行将每一行变成键值对的映射。
我想按地图中的某些键对此类文件的行进行排序,然后将它们保存为已排序。
我这样读取文件:
def parseTxtSimple(path: String):Array[String]=
{
Source.fromFile(path).getLines().toArray
}
然后,我使用compfunc对其进行排序:
val lines=parseTxtSimple(key+"/"+name)
// identify record keys from first line ( used by compfunc )
// strip is my own function that removes all \r and \n characters
val header=strip(lines.head).split("\t")
// sort lines
val lines_sorted:Array[String]=lines.tail.sortWith((leftE,rightE) => compfunc(leftE,rightE)).toArray
这是功能:
def compfunc(leftE:String,rightE:String):Boolean =
{
val leftEr=(header zip strip(leftE).split("\t")).toMap
val rightEr=(header zip strip(rightE).split("\t")).toMap
var ratingLeftE:Float=0.0.toFloat
var ratingRightE:Float=0.0.toFloat
if(leftEr.contains("rating")) ratingLeftE=myToFloat(leftEr("rating"))
if(rightEr.contains("rating")) ratingRightE=myToFloat(rightEr("rating"))
ratingLeftE > ratingRightE
}
我的问题是排序速度很慢,即使是20 MB的文本文件,程序也会用尽内存。
如果我读取文本文件而不是将字符串数组作为值数组(通过用“ \ t”分隔每一行)读取并使用这些预处理数组,而不是在compfunc中使用“ \ t”分隔它们并不好。
整个程序在这里找到:
https://github.com/fideplayerslist/fideplayerslist/blob/master/players.scala
def printOutput(header : Array[String], sorted : Array[String]) {
println(header.mkString("\t"))
sorted.foreach { x => println(x) }
}
def parseAndSortFile(lines: Array[String]): Unit = {
val header = lines.head.split("\t")
val ratingColumn = header.indexOf("ratings")
if (ratingColumn == -1) {
println("could not find ratings column");
} else {
val values = lines.tail.map { x => x.split("\t") }
val sorted = (values.sortBy[Float] { x => x(ratingColumn).toFloat }).map(x => x.mkString("\t"))
printOutput(header, sorted) // Replace this with whatever you want to do with the sorted data.
}
}
import scala.io._
val now = new Date().getTime
parseAndSortFile(Source.fromFile(fileName).getLines.toArray)
println(new Date().getTime-now)
这应该减少内存的使用并加快排序速度。但是,由于您是在内存中排序,因此始终会限制最大大小。确保您的堆足够大。
我使用了2 GB的堆大小。
32 MB文件耗时16秒
65 mb文件耗时34秒
98 mb文件耗时61秒
注意:在进行计时时,请注释掉对printOutput的调用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句