summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Suereth <Joshua.Suereth@gmail.com>2012-09-14 12:22:11 -0700
committerJosh Suereth <Joshua.Suereth@gmail.com>2012-09-14 12:22:11 -0700
commit261b1c785668ae42a29d9217cc4a8f305a724e2f (patch)
tree77024bdb9e9885b4cc84ea0095eaa84864caeb5d
parent83c1b1062957e50e5336c1b3409e54e0a5cce275 (diff)
parent47587dca4d3fb7c171cff21587b42f40bab77e21 (diff)
downloadscala-261b1c785668ae42a29d9217cc4a8f305a724e2f.tar.gz
scala-261b1c785668ae42a29d9217cc4a8f305a724e2f.tar.bz2
scala-261b1c785668ae42a29d9217cc4a8f305a724e2f.zip
Merge pull request #1304 from paulp/topic/empty-array-optimization
Topic/empty array optimization
-rw-r--r--src/compiler/scala/tools/cmd/gen/AnyVals.scala11
-rw-r--r--src/library/scala/Boolean.scala7
-rw-r--r--src/library/scala/Byte.scala8
-rw-r--r--src/library/scala/Char.scala8
-rw-r--r--src/library/scala/Double.scala8
-rw-r--r--src/library/scala/Float.scala8
-rw-r--r--src/library/scala/Int.scala8
-rw-r--r--src/library/scala/Long.scala8
-rw-r--r--src/library/scala/Short.scala8
-rw-r--r--src/reflect/scala/tools/nsc/io/VirtualFile.scala2
-rw-r--r--src/reflect/scala/tools/nsc/io/ZipArchive.scala2
-rw-r--r--test/files/run/empty-array.check3
-rw-r--r--test/files/run/empty-array.scala8
13 files changed, 83 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala
index 910804245b..b4f5641b98 100644
--- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala
+++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala
@@ -320,7 +320,13 @@ def unbox(x: java.lang.Object): @name@ = @unboxImpl@
override def toString = "object scala.@name@"
"""
- def nonUnitCompanions = "" // todo
+ def nonUnitCompanions = """
+/** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[@name@]
+ */
+final val emptyArray = new Array[@name@](0)"""
def cardinalCompanion = """
/** The smallest value representable as a @name@.
@@ -341,9 +347,6 @@ final val NaN = @boxed@.NaN
final val PositiveInfinity = @boxed@.POSITIVE_INFINITY
final val NegativeInfinity = @boxed@.NEGATIVE_INFINITY
-@deprecated("use @name@.MinPositiveValue instead", "2.9.0")
-final val Epsilon = MinPositiveValue
-
/** The negative number with the greatest (finite) absolute value which is representable
* by a @name@. Note that it differs from [[java.lang.@name@.MIN_VALUE]], which
* is the smallest positive value representable by a @name@. In Scala that number
diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala
index 440e546f19..d7311078ab 100644
--- a/src/library/scala/Boolean.scala
+++ b/src/library/scala/Boolean.scala
@@ -135,5 +135,12 @@ object Boolean extends AnyValCompanion {
*/
override def toString = "object scala.Boolean"
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Boolean]
+ */
+ final val emptyArray = new Array[Boolean](0)
}
diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala
index df0d2c73b1..02ef913fc5 100644
--- a/src/library/scala/Byte.scala
+++ b/src/library/scala/Byte.scala
@@ -625,6 +625,14 @@ object Byte extends AnyValCompanion {
*/
override def toString = "object scala.Byte"
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Byte]
+ */
+ final val emptyArray = new Array[Byte](0)
+
/** Language mandated coercions from Byte to "wider" types.
*/
implicit def byte2short(x: Byte): Short = x.toShort
diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala
index 1fa0c0d9e8..5a1bf16f1d 100644
--- a/src/library/scala/Char.scala
+++ b/src/library/scala/Char.scala
@@ -625,6 +625,14 @@ object Char extends AnyValCompanion {
*/
override def toString = "object scala.Char"
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Char]
+ */
+ final val emptyArray = new Array[Char](0)
+
/** Language mandated coercions from Char to "wider" types.
*/
implicit def char2int(x: Char): Int = x.toInt
diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala
index f058d7c26b..7bebbf9418 100644
--- a/src/library/scala/Double.scala
+++ b/src/library/scala/Double.scala
@@ -400,5 +400,13 @@ object Double extends AnyValCompanion {
/** The String representation of the scala.Double companion object.
*/
override def toString = "object scala.Double"
+
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Double]
+ */
+ final val emptyArray = new Array[Double](0)
}
diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala
index d942acec23..79ed2ac20b 100644
--- a/src/library/scala/Float.scala
+++ b/src/library/scala/Float.scala
@@ -401,6 +401,14 @@ object Float extends AnyValCompanion {
*/
override def toString = "object scala.Float"
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Float]
+ */
+ final val emptyArray = new Array[Float](0)
+
/** Language mandated coercions from Float to "wider" types.
*/
implicit def float2double(x: Float): Double = x.toDouble
diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala
index ae36413469..fa2f9a97e7 100644
--- a/src/library/scala/Int.scala
+++ b/src/library/scala/Int.scala
@@ -625,6 +625,14 @@ object Int extends AnyValCompanion {
*/
override def toString = "object scala.Int"
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Int]
+ */
+ final val emptyArray = new Array[Int](0)
+
/** Language mandated coercions from Int to "wider" types.
*/
implicit def int2long(x: Int): Long = x.toLong
diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala
index 4ee9383c2a..94204e893c 100644
--- a/src/library/scala/Long.scala
+++ b/src/library/scala/Long.scala
@@ -625,6 +625,14 @@ object Long extends AnyValCompanion {
*/
override def toString = "object scala.Long"
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Long]
+ */
+ final val emptyArray = new Array[Long](0)
+
/** Language mandated coercions from Long to "wider" types.
*/
implicit def long2float(x: Long): Float = x.toFloat
diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala
index 35c5fe3ff0..aef8608d2e 100644
--- a/src/library/scala/Short.scala
+++ b/src/library/scala/Short.scala
@@ -625,6 +625,14 @@ object Short extends AnyValCompanion {
*/
override def toString = "object scala.Short"
+
+ /** A highly reusable empty array, useful for avoiding
+ * allocations when you need one.
+ *
+ * @return a constant 0-length Array[Short]
+ */
+ final val emptyArray = new Array[Short](0)
+
/** Language mandated coercions from Short to "wider" types.
*/
implicit def short2int(x: Short): Int = x.toInt
diff --git a/src/reflect/scala/tools/nsc/io/VirtualFile.scala b/src/reflect/scala/tools/nsc/io/VirtualFile.scala
index be888e92e6..9061534edc 100644
--- a/src/reflect/scala/tools/nsc/io/VirtualFile.scala
+++ b/src/reflect/scala/tools/nsc/io/VirtualFile.scala
@@ -33,7 +33,7 @@ class VirtualFile(val name: String, override val path: String) extends AbstractF
//########################################################################
// Private data
- private var content = new Array[Byte](0)
+ private var content = Byte.emptyArray
//########################################################################
// Public Methods
diff --git a/src/reflect/scala/tools/nsc/io/ZipArchive.scala b/src/reflect/scala/tools/nsc/io/ZipArchive.scala
index d7ec209525..9d9d9a46f2 100644
--- a/src/reflect/scala/tools/nsc/io/ZipArchive.scala
+++ b/src/reflect/scala/tools/nsc/io/ZipArchive.scala
@@ -177,7 +177,7 @@ final class URLZipArchive(val url: URL) extends ZipArchive(null) {
class FileEntry() extends Entry(zipEntry.getName) {
override val toByteArray: Array[Byte] = {
val len = zipEntry.getSize().toInt
- val arr = new Array[Byte](len)
+ val arr = if (len == 0) Byte.emptyArray else new Array[Byte](len)
var offset = 0
def loop() {
diff --git a/test/files/run/empty-array.check b/test/files/run/empty-array.check
new file mode 100644
index 0000000000..bb0b1cf658
--- /dev/null
+++ b/test/files/run/empty-array.check
@@ -0,0 +1,3 @@
+0
+0
+0
diff --git a/test/files/run/empty-array.scala b/test/files/run/empty-array.scala
new file mode 100644
index 0000000000..e56c86df5c
--- /dev/null
+++ b/test/files/run/empty-array.scala
@@ -0,0 +1,8 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ println(Byte.emptyArray.length)
+ println(Double.emptyArray.length)
+ println(Boolean.emptyArray.length)
+ // okay okay okay
+ }
+}