Reputation: 4412
For fun I'm doing a simple OpenGL benchmark of various languages, and I just completed a Clojure implementation. It was running quite slow, however, so I decided to profile it with VisualVM, and I obtained some rather odd results. The following are snapshots from profiles of the Java and Clojure version respectively (both have identical rendering logic)
Note that glPopMatrix is the function taking up the most time in the Clojure implementation, by a significant margin, yet in the Java implementation glDrawArrays takes far more time. The code for the Clojure version is:
(defn render-pt [apt]
(GL11/glPopMatrix)
(GL11/glPushMatrix)
(GL11/glTranslatef (:x apt) (:y apt) (- 0 (:z apt)) )
(GL11/glScalef (* (:R apt) 2) (* (:R apt) 2) (* (:R apt) 2) )
(GL11/glDrawArrays GL11/GL_QUADS 0 24)
apt)
The function render-pt is mapped to an array of pt.
The code for the Java version is:
for (int i = minPt; i < numPts; i++) {
Pt pt = Pts[i];
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glTranslatef(pt.X, pt.Y, -pt.Z);
GL11.glScalef(pt.R * 2, pt.R * 2, pt.R * 2);
GL11.glDrawArrays(GL11.GL_QUADS, 0, 24);
}
The two functions seem the same to me; is there some mistake I'm making? Or am I reading the profile wrong?
Upvotes: 2
Views: 213
Reputation: 20194
Some differences between those functions:
(:x apt)
always returns a boxed numeric value, since it is not type hinted. pt.X
can likely return an unboxed numeric primitive, depending on the definition of Pt
.
(:x apt)
will do a hash lookup rather than the faster slot lookup that pt.X
does (unless apt is a Clojure record, you don't show enough code for me to know which this is so I assume it is a hash-map).
Numeric literals are Long
by default in Clojure, Integer
by default in Java.
Upvotes: 2