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.