If you have an algorithm that is already O(n^2), that’s already bad. But if your inner loop creates new objects that need to be garbage-collected, that’s terrible! Here’s a suggestion how we could help both the programmer and the compiler to deal with tight loops by introducing a new construct that restricts a block of code such that no new objects must be created.
fun doSomething() {
val stuff = Stuff() // new object, OK, outside tight block
tight {
val arr = stuff.data // getter must be tight, otherwise compiler error here
for (i in stuff.start ..< stuff.size) {
for (j in something.start ..< something.size) {
arr[i] = compute(i, j) // compute marked tight (see below)
}
}
}
}
tight fun compute(i: Int, j: Int) = TODO()
Inside the tight{} block, Kotlin code is restricted:
- It must not create any new objects on the Heap, whether explicitly nor implicitly; the Kotlin compiler must guarantee this
- Compiler error if you’re trying to create a new object inside the tight block (helps the programmer)
- It tells the compiler that this code should be particularly optimised for speed (more aggressive optimization)
- It must not call any functions except Kotlin language functions that are known to be “tight”, or functions that are marked to be “tight”, or functions that the compiler can infer to be tight
The tight keyword marks a function to be tight:
- The entire body of such a function must be tight
- Functions that are marked like this may be called from another tight function or tight block
- Functions that are not marked to be tight may only be called from another tight function or tight block if the compiler can infer that the function is tight (e.g. a getter that returns a value and no side-effects).
What do you think? I would appreciate this, because Kotlin is my language of choice, and I’m using it for game programming and other areas where other people would probably prefer C++.