--- /dev/null
+/*
+** Performance testing of floating-point decimal-to-binary conversion for
+** SQLite versus the standard library.
+**
+** This module compares library atof() against SQLite's sqlite3AtoF().
+** To go the other direction (binary-to-decimal) see fp-speed-1.c.
+**
+** To compile:
+**
+** make sqlite3.c
+** gcc -Os -c sqlite3.c
+** gcc -I. -Os test/fp-speed-2.c sqlite3.o -ldl -lm -lpthread
+**
+** To run the test:
+**
+** time ./a.out 0 10000000 <-- standard library
+** time ./a.out 1 10000000 <-- SQLite
+** time ./a.out 2 10000000 <-- test program overhead
+*/
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static const char *aVal[] = {
+ "-1.01638304862856430",
+ "+0.00492438073915869",
+ "+7.38187324073439948",
+ "+7.06785952192257171",
+ "+9.28072663198500256",
+ "+5.88710508619333946",
+ "-2.29980236212596628",
+ "-1.59035819249108474",
+ "+2.43134418168449782",
+ "-3.82909873289453990",
+ "+1.87879140627440013",
+ "+0.72706535604871466",
+ "+0.06395776979131836",
+ "+5.22923388793158619",
+ "+6.37476826728722313",
+ "+8.69723395383291069",
+ "-9.50744860515976919",
+ "-8.64802578453687530",
+ "-3.56575957757974703",
+ "-7.83231061797317613",
+ "+7.78138752741208003",
+ "-1.87397189283601965",
+ "+8.68981459155933572",
+ "+6.05667663598778378",
+ "+4.17033792171481606",
+ "+2.12838712887466515",
+ "-6.83952360838918106",
+ "-6.21142997639395291",
+ "-2.07535257426146373",
+ "+5.87274598039442902",
+ "+8.58889910620021018",
+ "+6.86244610313559176",
+ "-3.30539867566709051",
+ "-4.35968431527634449",
+ "+0.08341395201040996",
+ "-8.85819865489042224",
+ "-3.66220954287276982",
+ "-6.69658522970250632",
+ "+1.82041693474064884",
+ "+6.52345080386490003",
+ "+1.59230060182190114",
+ "+1.73625552916563894",
+ "+7.28754319768547858",
+ "+1.28358801059589267",
+ "+8.05162533203208194",
+ "+6.63246333993811454",
+ "-1.71265000702800620",
+ "+1.69957383415837123",
+ "+7.60487669237386637",
+ "+0.61591172354494550",
+ "+5.75448943554159432",
+ "+8.29702285926905818",
+ "-6.55319253601630674",
+ "+5.83213346061870300",
+ "+5.65571665095718917",
+ "+0.33227897084384087",
+ "-7.12106487766986866",
+ "-9.67212625267063433",
+ "-3.45839165713773950",
+ "+4.78960943232147507",
+ "-9.69260280400041378",
+ "+7.06838482753813854",
+ "-5.29701141821629619",
+ "-4.42870212009053932",
+ "+0.07288911557328087",
+ "-9.18554620258794474",
+ "+3.72941262341310077",
+ "+2.68574218827927192",
+ "-4.70706073336246853",
+ "+7.21758207682793342",
+ "-8.36784125342611634",
+ "+2.21748443042418221",
+ "+0.19498245886068610",
+ "-9.73340529556720719",
+ "-9.77938877669369998",
+ "-5.15611645874169315",
+ "-7.50489935777651747",
+ "+7.35560765686877845",
+ "-5.06816285755335998",
+ "+1.52097056420277478",
+ "-7.59897825350482960",
+ "+1.36541372033897758",
+ "-1.64417205546513720",
+ "-4.90424331961411259",
+ "-7.70636119616491307",
+ "+0.16994274609307662",
+ "+8.33743178495722168",
+ "-5.23553304804695800",
+ "-3.85100459421941479",
+ "-6.35136225443263398",
+ "+2.38693034844544289",
+ "+3.83527158716203602",
+ "-3.12631204931368879",
+ "-5.57947970025564908",
+ "-8.81098744795956043",
+ "-4.37273601202032169",
+ "-3.11099511896685399",
+ "-9.48418780317042682",
+ "-3.73984516683044072",
+ "+4.89840420089159599",
+};
+#define NN (sizeof(aVal)/sizeof(aVal[0]))
+
+
+#include "sqlite3.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv){
+ int i;
+ int cnt;
+ int fg;
+ double arSum[401];
+ char z[1000];
+
+ if( argc!=3 ){
+ fprintf(stderr, "Usage: %s FLAG COUNT\n", argv[0]);
+ return 1;
+ }
+ cnt = atoi(argv[2]);
+ fg = atoi(argv[1]);
+
+ switch( fg % 4 ){
+ case 0: printf("Doing %d calls to C-lib atof()\n", cnt); break;
+ case 1: printf("Doing %d calls to sqlite3AtoF()\n", cnt); break;
+ case 2: printf("Test overhead only for %d cases\n", cnt); break;
+ case 3: printf("Print the first %d cases\n", cnt); break;
+ }
+ memset(arSum, 0, sizeof(arSum));
+ for(i=0; i<cnt; i++){
+ int e, ex, len, ix;
+ ex = i%401;
+ e = ex - 200;
+ len = (i/401)%16 + 4;
+ ix = (i/(401*16))%NN;
+ memcpy(z, aVal[ix], len);
+ z[len++] = 'e';
+ if( e<0 ){
+ z[len++] = '-';
+ e = -e;
+ }else{
+ z[len++] = '+';
+ }
+ z[len++] = e/100 + '0';
+ z[len++] = (e/10)%10 + '0';
+ z[len++] = e%10 + '0';
+ z[len] = 0;
+ switch( fg % 4 ){
+ case 0: {
+ arSum[ex] += atof(z);
+ break;
+ }
+ case 1: {
+ double r = 0.0;
+ sqlite3_test_control(SQLITE_TESTCTRL_ATOF, z, &r);
+ arSum[ex] += r;
+ break;
+ }
+ case 2: {
+ double r = (double)i;
+ arSum[ex] += r;
+ break;
+ }
+ case 3: {
+ printf("%s\n", z);
+ break;
+ }
+ break;
+ }
+ }
+ for(i=1; i<=400; i++) arSum[0] += arSum[i];
+ printf("Grand total: %g\n", arSum[0]);
+ return 0;
+}