This is the Java code:
public static FloatBuffer createInterleavedVertexBuffer(AIMesh mesh) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(mesh.mNumVertices() * 8);
for (int i = 0; i < mesh.mNumVertices(); i++) {
var vertex = mesh.mVertices().get(i);
buffer.put(vertex.x());
buffer.put(vertex.y());
buffer.put(vertex.z());
var normal = mesh.mNormals().get(i);
buffer.put(normal.x());
buffer.put(normal.y());
buffer.put(normal.z());
var texCoords = mesh.mTextureCoords(0).get(i);
buffer.put(texCoords.x());
buffer.put(texCoords.y());
}
return buffer.flip();
}
And this is (as far as I can tell) equivalent Clojure code:
(defn create-vertex-buffer
[mesh]
(let [buffer (BufferUtils/createFloatBuffer (* (.mNumVertices mesh) 8))]
(doseq [index (range (.mNumVertices mesh))]
(let [vertex (.get (.mVertices mesh) index)
normal (.get (.mNormals mesh) index)
tex-coords (.get (.mTextureCoords mesh 0) index)]
(.put buffer (.x vertex))
(.put buffer (.y vertex))
(.put buffer (.z vertex))
(.put buffer (.x normal))
(.put buffer (.y normal))
(.put buffer (.z normal))
(.put buffer (.x tex-coords))
(.put buffer (.y tex-coords))))
(.flip buffer)))
However, the Clojure version runs about five times longer than the Java version.
Why is this?
Is there a way to improve the performance of the Clojure version?
(set! *warn-on-reflection* true)?(set! *warn-on-reflection* true)after the(ns ...)form and reload the namespace in your REPL. You'll see a bunch of reflection warnings coming from this function. Once if resolve them, the function should become close in performance to its Java version. BTW you can usedotimesinstead ofdoseq+range.