非常简单的问题:字节流和字符流之间的性能差异是什么?
我问的原因是因为我正在从文件中实现级别加载,最初我决定只使用字节流,因为它是最简单的类型,因此它应该表现最佳。但后来我认为能够通过文本编辑器读取和编写级别文件而不是编写更复杂的级别编辑器(开始时)可能会很好。为了使文本编辑器清晰可见,我需要使用字符流而不是字节流,所以我想知道这两种方法之间是否真的存在任何性能差异?目前它并不重要,因为级别加载很少,但我有兴趣知道将来参考,例如我可能需要动态加载硬盘驱动器的级别(大级别)。
答案 0 :(得分:4)
非常简单的问题:字节流和字符流之间的性能差异是什么?
我假设您将Input / OutputStream与Reader / Writer流进行比较。如果是这种情况,性能几乎相同。除非你有一个非常快的驱动器,否则瓶颈几乎肯定是磁盘,在这种情况下,你用Java做的事情并不重要。
我问的原因是因为我正在从文件中实现级别加载,最初我决定只使用字节流,因为它是最简单的类型,因此它应该表现最佳。但后来我认为能够通过文本编辑器读取和编写关卡文件而不是编写更复杂的关卡编辑器(开始时)可能会很好。
所有文件实际上都是一个字节流。因此,当您使用Reader / Writer时,它使用编码器将字节转换为字符并再次返回。没有什么可以阻止你直接读取和写入字节,这完全相同。
为了使文本编辑器清晰易读,我需要使用字符流而不是字节流,
你不会,但它可能会更容易。如果您只想要ASCII编码,则没有区别。如果您希望使用字符的非ASCII字符的UTF-8编码可能更简单。
所以我想知道这两种方法之间是否真的存在任何性能差异?
我会先担心正确性,然后再考虑性能。
我可能需要动态加载硬盘驱动器的级别(大级别)。
Java可以以大约90 MB / s的速度读/写文本,大多数硬盘和网络都不是那么快。但是,如果您需要在第二秒写入GB并且您拥有快速SSD,那么它可能会有所不同。 SSD可以执行500 MB / s或更高,然后我建议您使用NIO来最大化性能。
答案 1 :(得分:3)
Java只有一种流:字节流。类java.io.InputStream
和java.io.OutputStream
是按字节定义的。
要将字节转换为字符,最后将字符串转换为字符串,您将始终使用java.nio.charset
中的功能。但是,为方便起见,Java提供了Reader
和Writer
方法,这些方法可以将字节流调整为对字符和字符串进行操作的类似流的对象。
转换时,当然有CPU时间成本。但是,成本非常低。如果你设法编写一个性能主导这个成本的程序,你确实写了一个非常精益的程序。
答案 2 :(得分:0)
我不懂Java,所以拿一点盐就可以了。
字符流通常意味着您读取的每个内容都会根据当前区域设置解码为单个字符,这意味着对于国际化的文本数据而言,这些数据无法用128或256种不同的选择来表示。 Unicode系统中定义了所有可能字符的集合,并且编码定义了从单个字节到字符的方式。更多信息请访问:http://www.joelonsoftware.com/articles/Unicode.html
另一方面,字节流只读取0到255之间的值,并且不会尝试将它们解释为来自任何特定语言的字符。因此,字节流应该总是更快一些。但如果你有国际字符,除非你确切知道它们是如何被编码的,否则它们将无法正常显示。
对于大多数用途,人类可读的数据可以存储在ASCII中,每个字符只使用7位数据,并为您提供128个不同的字符。这可以被任何典型的文本编辑器读取,并且由于ASCII字符是Unicode和UTF-8编码的子集,因此您可以以字节或UTF-8字符读取ASCII文件,并且内容将保持不变。
如果您需要存储二进制值以实现更高效的序列化(例如,将数字123456789存储为4字节整数而不是9字节字符串),那么您需要切换到字节流,但是此时也放弃了人类可读性,因此问题变得有些无关紧要。
级别的大小不太可能对您的加载时间产生太大影响 - 典型的硬盘驱动器可以读取超过每秒100兆字节。代码对您来说最简单,只有在您的分析显示存在问题时才对其进行优化。