did you observe any jumps at some of the lower values as I did?
]]>Sin of 2480000 took 500000
Sin of 2490000 took 490000
Sin of 2500000 took 480000
Sin of 2510000 took 830000
Sin of 2520000 took 850000
Sin of 2530000 took 830000
Sin of 2540000 took 830000
Sin of 2550000 took 830000
Sin of 2560000 took 490000
Sin of 2570000 took 500000
Sin of 2580000 took 500000
Sin of 2590000 took 490000
Sin of 2600000 took 480000
Sin of 2610000 took 850000
Sin of 2620000 took 830000
Sin of 2630000 took 860000
Sin of 2640000 took 820000
Sin of 2650000 took 820000
Sin of 2660000 took 500000
Sin of 2670000 took 490000
Sin of 2680000 took 510000
Sin of 2690000 took 490000
Sin of 2700000 took 490000
Sin of 2710000 took 830000
Sin of 2720000 took 830000
Sin of 2730000 took 850000
Sin of 2740000 took 830000
Sin of 2750000 took 830000
Sin of 2760000 took 500000
Sin of 2770000 took 490000
Sin of 2780000 took 510000
Sin of 2790000 took 480000
Sin of 2800000 took 490000
Sin of 2810000 took 840000
Sin of 2820000 took 850000
Sin of 2830000 took 850000
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <ctime>
#include <vector>
using namespace std;
int main ()
{
time_t start, end;
int i, n = 10000000;
int sin_val;
int sin_max = 100000000;
int sin_step = 10000;
cout << "n: " << n << endl;
for (sin_val = 0; sin_val < 100000000; sin_val += sin_step) {
start = clock();
for (i = 0; i < n; i++) {
sin(sin_val);
}
end = clock();
cout << "Sin of " << sin_val << " took " << end - start << endl;
}
return 0;
}
int loops = 1000000;
long startTime, stopTime, elapsedTime;
for (int inputSize = 0; inputSize <= 3200000; inputSize += 100000)
{
startTime = System.currentTimeMillis();
for (int i = 0; i < loops; i++)
{
Math.sin(inputSize);
}
stopTime = System.currentTimeMillis();
elapsedTime = stopTime - startTime;
System.out.println("input size: " + inputSize + " elapsed Time: " + elapsedTime );
}
}
output:
input size: 0 elapsed Time: 109
input size: 100000 elapsed Time: 437
input size: 200000 elapsed Time: 422
input size: 300000 elapsed Time: 422
input size: 400000 elapsed Time: 437
input size: 500000 elapsed Time: 438
input size: 600000 elapsed Time: 469
input size: 700000 elapsed Time: 421
input size: 800000 elapsed Time: 438
input size: 900000 elapsed Time: 437
input size: 1000000 elapsed Time: 454
input size: 1100000 elapsed Time: 406
input size: 1200000 elapsed Time: 437
input size: 1300000 elapsed Time: 422
input size: 1400000 elapsed Time: 438
input size: 1500000 elapsed Time: 422
input size: 1600000 elapsed Time: 421
input size: 1700000 elapsed Time: 2922
input size: 1800000 elapsed Time: 3016
input size: 1900000 elapsed Time: 2953
input size: 2000000 elapsed Time: 2843
input size: 2100000 elapsed Time: 2969
input size: 2200000 elapsed Time: 2625
input size: 2300000 elapsed Time: 2781
input size: 2400000 elapsed Time: 2719
input size: 2500000 elapsed Time: 2719
input size: 2600000 elapsed Time: 2906
input size: 2700000 elapsed Time: 2797
input size: 2800000 elapsed Time: 2797
input size: 2900000 elapsed Time: 2735
input size: 3000000 elapsed Time: 2750
input size: 3100000 elapsed Time: 2703
input size: 3200000 elapsed Time: 3047
Press any key to continue . . .
i tested it several times and it consistently jumped to a much longer time after about the 1.6 million mark. My guess is the algorithm checks to see if the input is bigger than something around 1.6 million and if so, does things differently.
]]>I'll try testing in both java and C++, and let you know what I find.
]]>...keep in mind that you won't even get close to the library trig functions. Hash tables don't even beat them:
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <ctime>
#include <vector>
using namespace std;
vector<double> gerenateSineValues(int decimals) {
vector<double> result;
double d = pow((double)10, decimals);
int i;
for (i = 0; i < pow((double)10, decimals+1); i++) {
result.push_back(sin(i/d));
}
return result;
}
int main ()
{
time_t start_hash, end_hash, start_lib, end_lib;
int n, r, loops = 100000000;
double r2;
vector<double> sinValues = gerenateSineValues(5);
srand(time(NULL));
cout << "Starting hash method...";
cout.flush();
start_hash = clock();
for (n = 0; n < loops; n++) {
r = rand() % 1000000; //5 decimal places, 1 integer
sinValues[r];
}
end_hash = clock();
cout << "DONE" << endl;
cout << "Starting lib method...";
cout.flush();
start_lib = clock();
for (n = 0; n < loops; n++) {
r2 = (double)(rand() % 10000000)/((double)RAND_MAX+1);
sin(r2);
}
end_lib = clock();
cout << "DONE" << endl;
cout << "Hash: " << end_hash - start_hash << endl;
cout << "Lib: " << end_lib - start_lib << endl;
cout << endl;
return 0;
}
Output:
[root@localhost Desktop]# ./a.out
Starting hash method...DONE
Starting lib method...DONE
Hash: 7850000
Lib: 5320000
Perhaps now I should consider how many iterations are necessary based on the input size.
]]>double xSquared = x*x; // compute x squared ahead of time
double sum = x; // add the first term to the accumulated sum
double previousTerm = x;
for (int n = 3; n < INFINITY; n+= 2) // continue on from the second term
{
// compute this term using the previous term
previousTerm = -previousTerm*xSquared/( (n*(n-1));
sum += previousTerm;
}
return sum;
Be a little quicker?
]]>or in sumation:
note that
(2n -1)! = (2n-1)(2n-2)(2n - 3)! and (2n - 3)! is the factorial of the preceding term.
Also
which also appears in the preceding term. Thusor if we allow n to move up in increments of 2 and shift the starting point, then we have
thus we could compute the sum as follows:
double xSquared = x*x; // compute x squared ahead of time
double sum = x; // add the first term to the accumulated sum
double previousTerm = x;
double currentTerm;
for (int n = 3; n < INFINITY; n+= 2) // continue on from the second term
{
// compute this term using the previous term
currentTerm = -previousTerm*xSquared/( (n*(n-1));
sum += currenTerm;
previousTerm = currentTerm;
}
return sum;
what do you think? Any ways we could make it even faster?
]]>