(sorry if you received an earlier mail from me that was half-formed, I hit
send by accident)
Hi there, I'm quite new to Clojure, and was trying to do some very simple
benchmarking with other languages. I was surprised by the floating-point
results I got, which differed (for the same calculation, using doubles)
compared to the other languages I tried (including C++, SuperCollider, Lua,
Python).
My benchmark iteratively runs a function 100M times: g(x) <-- sin(2.3x) +
cos(3.7x), starting with x of 0.
In the other languages, I always got the result *0.0541718*..., but in
Clojure I get *0.24788989*.... I realize this is a contrived case, but --
doing an identical sequence of 64-bit floating-point operations on the same
machine should give the same answer. Note that if you only run the
function for about ~110 iterations, you get the same answer in Clojure (or
very close), but then it diverges.
I assume my confusion is due to my ignorance of Clojure and/or Java's math
library. I don't think I'm using 32-bit floats or the "BigDecimal" type (I
even explicitly converted to double, but got the same results, and if I
evaluate the *type* it tells me *java.lang.Double*, which seems right).
Maybe Clojure's answer is "better", but I do find it strange that it's
different. Can someone explain this to me?
Here are some results:
*Clojure: ~23 seconds*
(defn g [x] (+ (Math/sin (* 2.3 x)) (Math/cos (* 3.7 x))))
(loop [i 100000000 x 0] (if (pos? i) (recur (dec i) (g x)) x))
;; final x: *0.24788989279493556 (???)*
*C++ (g++ -O2): ~4 seconds*
double g(double x) {
return std::sin(2.3*x) + std::cos(3.7*x);
}
int main() {
double x = 0;
for (int i = 0; i < 100000000; ++i) {
x = g(x);
}
std::cout << "final x: " << x << std::endl;
return 0;
}
// final x: *0.0541718*
*Lua: ~39 seconds*
g = function(x)
return math.sin(2.3*x) + math.cos(3.7*x)
end
x = 0; for i = 1, 100000000 do x = g(x) end
-- Final x: *0.054171801051906*
*Python: ~72 seconds*
def g(x):
return math.sin(2.3*x) + math.cos(3.7*x)
x = 0
for i in xrange(100000000):
x = g(x)
# Final x: *0.05417180105190572*
*SClang: ~26 seconds*
g = { |x| sin(2.3*x) + cos(3.7*x) };
f = { |x| 100000000.do{ x = g.(x) }; x};
bench{ f.(0).postln };
// final x: *0.054171801051906* (same as C++, Lua, Python; different from
Clojure)
Thanks,
Glen.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.