Parsing of floating point numbers was very slow, due to calling (expt 10) to scale the decimal part. This change uses a look-up table instead, falling back to calling expt only if there are more than 20 decimal digits in the input.
Test case:
(let ((s "{\"foo\":42.17,\"bar\":12.3456789012345}")) (time (dotimes (_ 1000000) (jonathan:parse s :as :alist))))
Before change, on CCL 1.11.5 (LinuxX8664): took 13,166,328 microseconds (13.166328 seconds) to run.
After change, on CCL: took 1,488,017 microseconds (1.488017 seconds) to run.
Before change, on SBCL 1.4.15: 1.757 seconds of real time
After change, on SBCL: 0.814 seconds of real time.
Coverage remained the same at 71.186% when pulling 43a1f6ab8c81412807dfbffc27197d19889657c2 on jlahd:float-reading-optimization into 1f448b4f7ac8265e56e1c02b32ce383e65316300 on Rudolph-Miller:master.
Parsing of floating point numbers was very slow, due to calling (expt 10) to scale the decimal part. This change uses a look-up table instead, falling back to calling expt only if there are more than 20 decimal digits in the input.
Test case:
(let ((s "{\"foo\":42.17,\"bar\":12.3456789012345}")) (time (dotimes (_ 1000000) (jonathan:parse s :as :alist))))
Before change, on CCL 1.11.5 (LinuxX8664):
took 13,166,328 microseconds (13.166328 seconds) to run.
After change, on CCL:took 1,488,017 microseconds (1.488017 seconds) to run.
Before change, on SBCL 1.4.15:
1.757 seconds of real time
After change, on SBCL:0.814 seconds of real time
.