`
winnerbao
  • 浏览: 10035 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Groovy File.append很慢,因为每次都要打开/关闭文件

 
阅读更多

[介绍]

Groovy File.append很慢,因为每次都要打开/关闭文件。如果你的处理程序要多次append信息到文件中,那将非常非常的慢!

 

本文将介绍我最近在使用File.append中碰到的性能问题,以及解决的方式。

 

Groovy是什么?

https://en.wikipedia.org/wiki/Groovy_%28programming_language%29

http://www.groovy-lang.org/

 

[问题]

最近(201504)写一个文件处理程序,使用了Groovy的File.append,结果很坑人呀。一个500多兆的文件,弄了几个小时。

 

[原因]

使用JVisualVM一看,大部分时间在FileOutputStream.close. 找到源代码一看(源码已附上),果然啊,每次都要打开、关闭文件,那必须慢啊。

 

 

[解决方案]

直接使用java的FileWriter.append(), 而避免使用Groovy的 ResourceGroovyMethods.append()

 

使用更大的buffersize, BufferedOutputSteam可以提高效率. 注意: BufferedWriter不会帮助你太多,参考 [实践]Log4j 1.X BufferedIO不工作(<8k时)原因分析, 暨深入探查Java IO Output BufferSizehttp://winnerbao.iteye.com/blog/2219736

 

 

[特别提示]

当发现程序效率很低时,不要直接想当然的&急冲冲的将自己怀疑的地方改掉。再想想,并用profiling工具(推荐jvisualvm)看看, 来验证你的猜测。

此处想起某本书(Bob? Joe? 忘了)上写,“你要知道并方便的profiling你的程序”。几年前就读过,但是有什么用 眨眼

 

我当时就犯了一个错误,想当然的以为每次写入的东西太少而引起的缓慢。然后就将文件内容缓存到StringBuilder里面,增加每次写入数量,结果“果然快了!”。当时还以为自己有点牛X。实际上是因为缓存了内容,而减少了append(即close)的次数。

 

 

[附录]

 

我的处理程序片段

sourceCSVDealsFile.eachLine { csvDealLine, lineNumber ->

	if(lineNumber == 1){
		//header
		destCSVDealsFile.append(csvDealLine+"\n")
		excludedCSVDealsFile.append(csvDealLine+"\n")
		return
	}
	
	if(shouldBeExcluded(csvDealLine)){
		excludedCSVDealsFile.append(csvDealLine+"\n")
	}else{
		destCSVDealsFile.append(csvDealLine+"\n")
	}
	
}

 

 

Groovy File.append (ResourceGroovyMethods.append) 源码

http://grepcode.com/file/repo1.maven.org/maven2/com.ovea.tajin/tajin-all/1.0.b1/org/codehaus/groovy/runtime/ResourceGroovyMethods.java#ResourceGroovyMethods.append%28java.io.File%2Cjava.lang.Object%2Cjava.lang.String%29

 

    /**
     * Write the text to the File, using the specified encoding.
     *
     * @param file    a File
     * @param text    the text to write to the File
     * @param charset the charset used
     * @throws IOException if an IOException occurs.
     * @since 1.0
     */
    public static void write(File file, String text, String charset) throws IOException {
        BufferedWriter writer = null;
        try {
            writer = newWriter(file, charset);
            writer.write(text);
            writer.flush();

            Writer temp = writer;
            writer = null;
            temp.close();
        } finally {
            closeWithWarning(writer);
        }
    }

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics