PlayFramework2.0x でファイルをストリーム転送する
実装そのものは大した問題ではなく、
http://scala.playframework.org/documentation/2.0.4/ScalaStream
なわけなのだが、どれだけ速度が出るものなのか確認してみる。
設定をこう書いて、
directory.path="C:/Users/XXXX/Pictures" directory.extension="jpg"
コードをこう書いて
def loadFile(fileName:String) = Action { Logger.apply("application").logger.debug("file : %s".format(fileName)) val config = Play.current.configuration val firectoryPath = config.getString("directory.path").get val file = new File("%s/%s".format(firectoryPath, fileName)) val fileContent: Enumerator[Array[Byte]] = Enumerator.fromFile(file) SimpleResult( header = ResponseHeader(200), body = fileContent ) }
URL をざくっと書く
GET /file/:filename controllers.Application.loadFile(filename:String)
ファイルをWeb経由で落とすだけならこれでOK。よろしいでは転送速度だ。
で、検証しようかと思ったのだが、ローカルエリア意味がねえ、、、、メインマシンのHDアクセス速度がネットワークアダプタの限界速度値を上回ってる(普通はそうだわな?)ので、この条件でアクセスしてもアダプタ性能が出るだけだ、、、、。
Javaのファイルストリームアクセス速度を測るしかないか。
一応 302kb の画像に下記の処理をループし、10回計測する。
val firectoryPath = "C:/Users/azalea/Pictures/055.jpg" val file = new File(firectoryPath) val stream = new FileInputStream(file) val reader = new InputStreamReader(stream) val buffer:Array[Char] = Array.fill(10)(0) val start = System.currentTimeMillis(); var length = 0 while (length > -1) length = reader.read(buffer) val end = System.currentTimeMillis(); reader.close() stream.close() println("ExecutedTime: " + (end - start))
結果が
ExecutedTime: 27 ExecutedTime: 26 ExecutedTime: 24 ExecutedTime: 25 ExecutedTime: 24 ExecutedTime: 23 ExecutedTime: 24 ExecutedTime: 24 ExecutedTime: 24 ExecutedTime: 24
で、バッファサイズに影響を受けるという情報があるので、試しにやってみる。
val buffer:Array[Char] = Array.fill(300000)(0)
という感じで
ExecutedTime: 20 ExecutedTime: 21 ExecutedTime: 20 ExecutedTime: 21 ExecutedTime: 20 ExecutedTime: 20 ExecutedTime: 20 ExecutedTime: 20 ExecutedTime: 20 ExecutedTime: 19
この程度のサイズじゃ微妙か、、、、でも意味がないわけでは無さそう。
ということで、3.6MBのファイルで比較
100 バイトアクセス
ExecutedTime: 132 ExecutedTime: 131 ExecutedTime: 124 ExecutedTime: 125 ExecutedTime: 128 ExecutedTime: 123 ExecutedTime: 125 ExecutedTime: 123 ExecutedTime: 123 ExecutedTime: 126
300K バイトアクセス
ExecutedTime: 91 ExecutedTime: 90 ExecutedTime: 91 ExecutedTime: 91 ExecutedTime: 91 ExecutedTime: 90 ExecutedTime: 91 ExecutedTime: 91 ExecutedTime: 91 ExecutedTime: 91
おおぅバッファサイズを弄るのには意味がありそう。
で、Play でそれを設定する場合は第二匹数にサイズを指定する。
今日日サーバのメモリ単価は安かろうし、速度上げるならこれで 40% 程度改善が見込めると、、、、マシンによるんだろうけど。
val fileContent: Enumerator[Array[Byte]] = Enumerator.fromFile(file, 300000)