下面的代碼運行用戶和寫入文件的比較。我已經刪除了一些代碼,使其儘可能簡明,但速度是一個問題,也是在這個代碼:使用參數圖提高性能
import scala.collection.JavaConversions._
object writedata {
def getDistance(str1: String, str2: String) = {
val zipped = str1.zip(str2)
val numberOfEqualSequences = zipped.count(_ == ('1', '1')) * 2
val p = zipped.count(_ == ('1', '1')).toFloat * 2
val q = zipped.count(_ == ('1', '0')).toFloat * 2
val r = zipped.count(_ == ('0', '1')).toFloat * 2
val s = zipped.count(_ == ('0', '0')).toFloat * 2
(q + r)/(p + q + r)
} //> getDistance: (str1: String, str2: String)Float
case class UserObj(id: String, nCoordinate: String)
val userList = new java.util.ArrayList[UserObj] //> userList : java.util.ArrayList[writedata.UserObj] = []
for (a <- 1 to 100) {
userList.add(new UserObj("2", "101010"))
}
def using[A <: { def close(): Unit }, B](param: A)(f: A => B): B =
try { f(param) } finally { param.close() } //> using: [A <: AnyRef{def close(): Unit}, B](param: A)(f: A => B)B
def appendToFile(fileName: String, textData: String) =
using(new java.io.FileWriter(fileName, true)) {
fileWriter =>
using(new java.io.PrintWriter(fileWriter)) {
printWriter => printWriter.println(textData)
}
} //> appendToFile: (fileName: String, textData: String)Unit
var counter = 0; //> counter : Int = 0
for (xUser <- userList.par) {
userList.par.map(yUser => {
if (!xUser.id.isEmpty && !yUser.id.isEmpty)
synchronized {
appendToFile("c:\\data-files\\test.txt", getDistance(xUser.nCoordinate , yUser.nCoordinate).toString)
}
})
}
}
上面的代碼以前是勢在必行的解決方案,所以.PAR功能是內內和外循環。我試圖將其轉換爲更實用的實現,同時也利用了Scala的並行集合框架。
在這個例子中,數據集的大小是10,但在代碼im工作在 大小是8000轉換爲64'000'000比較。我是 使用一個同步塊,以便多個線程不寫入 同一個文件在同一時間。甲性能改良效果IM考慮 被填充內環內的單獨集合(userList.par.map(yUser => {) ,然後寫該集合出單獨的文件中。
是否有其他的方法,我可以使用改善性能,以便我可以 處理包含8000個項目的列表,而不是上面的100個示例?
1.您看起來像'appendToFile'方法每次寫入文件時打開並關閉文件寫入器。 嘗試在處理的開始處打開文件並在最後關閉它。另外,儘量不要阻止'par'處理的線程。使用ArrayBlockingQueue並從另一個執行上下文寫入文件。使用AtomicInt或AtomicLong作爲計數器 –
也建議使用StringBuffer(因爲它是線程安全的),並定期將其刷新到PrintWriter –