Tuesday, January 5, 2010

Another observation on Groovy's speed

Not specifically about CouchDB, but have been experimenting with
REST-based Java/Groovy DAOs using CouchDB as the backend. Thought folks
here might be interested in the info.

I created some REST DAOs using Groovy's HttpBuilder, and Spring's
RestTemplate. Both use Google's GSON library for serializing to JSON.

Examples of create method:

Spring's RestTemplate implementation:


public String create(Pojo pojo) {
Map response = restTemplate.postForObject(url, pojo, Map.class);
String id = (String)response.get("id");
String rev = (String)response.get("rev");
pojo.setKey(id);
pojo.setRevision(rev);

return pojo.getKey();
}

Groovy's HttpBuilder implementation:

String create(Pojo pojo) {
httpBuilder.request(POST, JSON) {
send JSON, toJson(pojo)
response.success = {resp, json ->
pojo.key = json.id as String
pojo.revision = json.rev as String
}
}
pojo.key
}

The Spring implementation is nearly 50 times faster than the Groovy implementation!

Of course, the Groovy implementation was much easier to learn and implement the Couch API with and was great for prototyping.

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")



Saturday, December 5, 2009

ScrumMasters pointless?

Scrum itself can be quite effective, but I'm starting to believe that a dedicated ScrumMaster role is pointless.

The most effective teams are best at learning agile techniques themselves and things like "conflict resolution". If you really need someone, rotate the role amongst team members.

The cynic in me thinks the role was promoted to help Scrum adoption and buy-in by the Project Management corps (who would otherwise feel threatened by Scrum/agile).

Friday, November 27, 2009

CouchDB attachments, mapping JSON to Java

Wasn't obvious to me how to map this in Java JSON libs, but the way that CouchDB stores references to a document's attachments corresponds to a Map:

"_attachments":{
"ALPHA.png":{
"stub":true,
"content_type":"CONTENT/TYPE",
"length":2351959,
"revpos":1
},
"CHARLIE.png":{
"stub":true,
"content_type":"CONTENT/TYPE",
"length":6376790,
"revpos":1
},
"BRAVO.png":{
"stub":true,
"content_type":"CONTENT/TYPE",
"length":2361940,
"revpos":1
}
}

E.g.:

Map attachments;

Monday, November 16, 2009

Web Framework Names of the Future

Following the trend with Ruby on Rails, Groovy on Grails, here are my predictions for web frameworks of the future (with a little help from a script, favs in bold):

  • Boobies on Bails
  • Brewski on Brails
  • Doobie on Dales
  • Droopy on Drails
  • Fruity on Frails
  • Goudy on Gails (great font support)
  • Hippie on Hails
  • Judy on Jails (isn't that a show?)
  • Loopy on Lails
  • Moody on Males
  • n00b on Nails
  • Poopy on Pails
  • Scooby on Scales
  • Slurpie on Slails
  • Snoopy on Snails
  • Soupy on Sales :-)
  • Spooky on Spails
  • Troopy on Trails
  • Voodoo on Veils (how cool is that?)
  • Wookie on Whales
  • Zippy on Zales


Saturday, November 14, 2009

Notes on Scala and Groovy

I love Scala's:
  • concurrency/actor support
  • combined Class definition with primary constructor
  • operators == methods
  • sensible typing

I dislike:
  • Collections are not 1:1 compatible with Java Collections
  • Terse syntax still feels awkward to a 10 year Java veteran

I love Groovy's:
    • Close but improved Java-like syntax
    • Closures
    • Builder libs

    I dislike:
    • Hard to remember when parenthesis are optional.
    • Lack of anonymous classes (such a pain for libs like Wicket)


    Maybe call it.... Scooby? ;-)

    Spring RestTemplate, PUT, DELETE

    Spring's RestTemplate is nice, but I don't understand why it doesn't easily support extracting response objects for delete and put calls...
    E.g. CouchDB REST API uses this approach.

    Yeah there's the execute method, but then you need to reimplement the RestTemplate.PostPutCallback class, which is private..