Pattern matching isn't really identical to if/else's. If you look at the bytecode generated by pattern matching, each case is a function, i.e. in this case the pattern matching would generate 5 functions. The scala compiler might do optimization better in the future, but for now that's what it does.

You can do something like this:

```scala
def writableCloneFunc[T] = classTag[T] match {
  case classTag[Text] => (obj: Writable) => new Text(w.asInstanceOf[Text].getBytes)
  case classTag[LongWritable] => (obj: Writable) => new LongWritable(obj.asInstanceOf[LongWritable].get)
  ...
}
```
and then just use the function returned by this in the inner loop. I believe the change is simple enough. If it is too complicated, I wouldn't worry about this "premature" optimization. 

Technically you can argue that the JVM might be able to JIT away the slow pattern matching in the inner loop, but it takes at least 10k runs plus some additional overhead for the JVM to consider JITing just one of the pattern match case.