성능 문제는 데이터를 읽는 방식과 관련이 없습니다. 이미 버퍼링되었습니다. 실제로 라인을 통해 반복 할 때까지 아무런 변화가 없습니다 :
// measures time taken by enclosed code
def timed[A](block: => A) = {
val t0 = System.currentTimeMillis
val result = block
println("took " + (System.currentTimeMillis - t0) + "ms")
result
}
val source = timed(scala.io.Source.fromFile("test.txt")) // 200mb, 500 lines
// took 0ms
val lines = timed(source.getLines)
// took 0ms
timed(lines.next) // read first line
// took 1ms
// ... reset source ...
var x = 0
timed(lines.foreach(ln => x += ln.length)) // "use" every line
// took 421ms
// ... reset source ...
timed(lines.toArray)
// took 915ms
내 하드 드라이브에 대한 초당 5백메가바이트의 읽기 속도를 고려, 최적의 시간의 여지가 없다는 것을 의미 200메가바이트에 대한 400ms 일에있을 것입니다 이터레이터를 배열로 변환하지 않는 것 이외의 개선 사항.
응용 프로그램에 따라 배열 대신 직접 이터레이터를 사용할 수 있습니다. 메모리에서 이러한 거대한 배열로 작업하는 것이 어쨌든 성능 문제가 될 것이기 때문입니다.
편집 : 난 당신이 더 배열을 변환하려는, 가정 귀하의 의견에서은 (당신이 숫자 배열을 읽고 말했듯이 아마 열에 라인을 분할). 이 경우 나는 읽는 동안 변형을하는 것이 좋습니다. 예를 들어 :
source.getLines.map(_.split(",").map(_.trim.toInt)).toArray
는 다른에 전체 거대한 배열을 변환하지 않기 때문에 (이 1.9s 대신 2.5s 나를 위해)
source.getLines.toArray.map(_.split(",").map(_.trim.toInt))
보다 상당히 빠르지 만 단지 각 라인 개별적으로 단일 배열로 끝납니다 (힙 공간의 절반 만 사용함). 또한 파일을 읽는 것이 병목이므로 판독하는 동안 변환하면 CPU 사용률이 향상됩니다.
'소스'는'BufferedSource'를 사용하는데, 이는 다시'BufferedReader'를 사용합니다. 따라서 이미 데이터 블록을 메모리로 읽습니다. 바이트 단위로 읽지는 않습니다. – DNA
@DNA java.nio를 사용하여 (심지어) 더 빠른 접근법이 있는지 궁금해하는 관측에 많은 감사를드립니다 ... – elm
* 매우 큰 파일 *을 정의하고 그 데이터로 무엇을 할 것인지 (분할 후 그 행은 다음과 같습니다. –