Tuesday, January 5, 2010

Scala vs Groovy performance

Not an official performance comparison, just some observations made in the past week or two.

Quick port of some old Java graphics code I wrote into both Groovy and Scala scripts.
Execution time for main loop:

Groovy: 20.319 seconds
Scala: 0.335 seconds

I know this is like comparing apples and oranges, but still... 60 times slower?

I'm pretty turned-off from considering Groovy for anything other than quick prototyping or non-application scripting.

Code below (not meant to be high-quality examples of either language):

Scala:


import java.awt.image.BufferedImage
import java.awt.image.BufferedImage.TYPE_INT_ARGB
import java.io.File
import javax.imageio.ImageIO.{read, write}

val file = args(0)
val input = read(new File(file))

val w = (input.getWidth / 2).asInstanceOf[Int] * 2
val h = input getHeight
var output = new BufferedImage(w / 2, h / 2, TYPE_INT_ARGB)
var r: Int = _
var g: Int = _
var b: Int = _
var lines = new Array[Array[Int]](w, 4)

val time = System.currentTimeMillis
println("Output: " + file.replace(".", "-clear_") + ".png")

(0 until (h - 1, 2)) foreach { y =>
(0 until w) foreach { x =>
val rgb = input getRGB (x, y)
val rgb2 = input getRGB (x, y + 1)

lines(x)(0) = (((rgb & 0xFF0000) >> 16) + ((rgb2 & 0xFF0000) >> 16)) / 2
lines(x)(1) = (((rgb & 0x00FF00) >> 8) + ((rgb2 & 0x00FF00) >> 8)) / 2
lines(x)(2) = ((rgb & 0x0000FF) + (rgb2 & 0x0000FF)) / 2
lines(x)(3) = (((rgb >> 24) & 0xFF) + ((rgb2 >> 24) & 0xFF)) / 2

if (x >= 2 && x % 2 == 0) {
r = lines(x - 2)(0)
g = lines(x - 1)(1)
b = lines(x)(2)

val a = (lines(x)(3) + lines(x - 1)(3) + lines(x - 2)(3)) / 3
val rgb3 = (a << 24) | (r << 16) | (g << 8) | b
output setRGB ((x / 2), (y / 2), rgb3)
}
}
}
println (System.currentTimeMillis - time)

write(output, "PNG", new File(file.replace(".", "-clear_") + ".png"))

Groovy:


import java.awt.image.BufferedImage
import static java.awt.image.BufferedImage.TYPE_INT_ARGB
import javax.imageio.ImageIO

def file = args[0]

println "Input: ${file}"

def BufferedImage input = ImageIO.read(new File(file))
def int w = (input.width / 2 as int) * 2
def int h = input.height
def BufferedImage output = new BufferedImage(w / 2 as int, h / 2 as int, TYPE_INT_ARGB)
def int r, g, b
def int[][] lines = new int[w][4]

println "Output: ${file.replace(".", "-clear_")}.png"

def time = System.currentTimeMillis()

for (int y = 0; y < h - 1; y += 2) {
(0..<w).each { int x ->
def int rgb = input.getRGB(x, y)
def int rgb2 = input.getRGB(x, y + 1)

lines[x][0] = (((rgb & 0xFF0000) >> 16) + ((rgb2 & 0xFF0000) >> 16)) / 2
lines[x][1] = (((rgb & 0x00FF00) >> 8) + ((rgb2 & 0x00FF00) >> 8)) / 2
lines[x][2] = ((rgb & 0x0000FF) + (rgb2 & 0x0000FF)) / 2
lines[x][3] = (((rgb >> 24) & 0xFF) + ((rgb2 >> 24) & 0xFF)) / 2

if (x >= 2 && x % 2 == 0) {
r = lines[x - 2][0]
g = lines[x - 1][1]
b = lines[x][2]

int a = (lines[x][3] + lines[x - 1][3] + lines[x - 2][3]) / 3
int rgb3 = (a << 24) | (r << 16) | (g << 8) | b
output.setRGB((x / 2) as int, (y / 2) as int, rgb3)
}
}
}
println(System.currentTimeMillis() - time)

ImageIO.write output, "PNG", new File("${file.replace(".", "-clear_")}.png")



No comments:

Post a Comment