]> git.saurik.com Git - apple/icu.git/blame_incremental - icuSources/test/perf/howExpensiveIs/sieve.cpp
ICU-491.11.3.tar.gz
[apple/icu.git] / icuSources / test / perf / howExpensiveIs / sieve.cpp
... / ...
CommitLineData
1/*
2 **********************************************************************
3 * Copyright (c) 2011,International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 */
7
8#include "unicode/utimer.h"
9#include <stdio.h>
10#include <math.h>
11#include <stdlib.h>
12
13#include "sieve.h"
14
15/* prime number sieve */
16
17U_CAPI double uprv_calcSieveTime() {
18#if 1
19#define SIEVE_SIZE U_LOTS_OF_TIMES /* standardized size */
20#else
21#define SIEVE_SIZE <something_smaller>
22#endif
23
24#define SIEVE_PRINT 0
25
26 char sieve[SIEVE_SIZE];
27 UTimer a,b;
28 int i,k;
29
30 utimer_getTime(&a);
31 for(int j=0;j<SIEVE_SIZE;j++) {
32 sieve[j]=1;
33 }
34 sieve[0]=0;
35 utimer_getTime(&b);
36
37
38#if SIEVE_PRINT
39 printf("init %d: %.9f\n", SIEVE_SIZE,utimer_getDeltaSeconds(&a,&b));
40#endif
41
42 utimer_getTime(&a);
43 for(i=2;i<SIEVE_SIZE/2;i++) {
44 for(k=i*2;k<SIEVE_SIZE;k+=i) {
45 sieve[k]=0;
46 }
47 }
48 utimer_getTime(&b);
49#if SIEVE_PRINT
50 printf("sieve %d: %.9f\n", SIEVE_SIZE,utimer_getDeltaSeconds(&a,&b));
51
52 if(SIEVE_PRINT>0) {
53 k=0;
54 for(i=2;i<SIEVE_SIZE && k<SIEVE_PRINT;i++) {
55 if(sieve[i]) {
56 printf("%d ", i);
57 k++;
58 }
59 }
60 puts("");
61 }
62 {
63 k=0;
64 for(i=0;i<SIEVE_SIZE;i++) {
65 if(sieve[i]) k++;
66 }
67 printf("Primes: %d\n", k);
68 }
69#endif
70
71 return utimer_getDeltaSeconds(&a,&b);
72}
73static int comdoub(const void *aa, const void *bb)
74{
75 const double *a = (const double*)aa;
76 const double *b = (const double*)bb;
77
78 return (*a==*b)?0:((*a<*b)?-1:1);
79}
80
81double midpoint(double *times, double i, int n) {
82 double fl = floor(i);
83 double ce = ceil(i);
84 if(ce>=n) ce=n;
85 if(fl==ce) {
86 return times[(int)fl];
87 } else {
88 return (times[(int)fl]+times[(int)ce])/2;
89 }
90}
91
92double medianof(double *times, int n, int type) {
93 switch(type) {
94 case 1:
95 return midpoint(times,n/4,n);
96 case 2:
97 return midpoint(times,n/2,n);
98 case 3:
99 return midpoint(times,(n/2)+(n/4),n);
100 }
101 return -1;
102}
103
104double qs(double *times, int n, double *q1, double *q2, double *q3) {
105 *q1 = medianof(times,n,1);
106 *q2 = medianof(times,n,2);
107 *q3 = medianof(times,n,3);
108 return *q3-*q1;
109}
110
111U_CAPI double uprv_getMeanTime(double *times, uint32_t timeCount, double *marginOfError) {
112 double q1,q2,q3;
113 int n = timeCount;
114
115 /* calculate medians */
116 qsort(times,n,sizeof(times[0]),comdoub);
117 double iqr = qs(times,n,&q1,&q2,&q3);
118 double rangeMin= (q1-(1.5*iqr));
119 double rangeMax = (q3+(1.5*iqr));
120
121 /* Throw out outliers */
122 int newN = n;
123#if U_DEBUG
124 printf("iqr: %.9f, q1=%.9f, q2=%.9f, q3=%.9f, max=%.9f, n=%d\n", iqr,q1,q2,q3,(double)-1, n);
125#endif
126 for(int i=0;i<newN;i++) {
127 if(times[i]<rangeMin || times[i]>rangeMax) {
128#if U_DEBUG
129 printf("Knocking out: %.9f from [%.9f:%.9f]\n", times[i], rangeMin, rangeMax);
130#endif
131 times[i--] = times[--newN]; // bring down a new value
132 }
133 }
134
135 /* if we removed any outliers, recalculate iqr */
136 if(newN<n) {
137#if U_DEBUG
138 printf("Kicked out %d, retrying..\n", n-newN);
139#endif
140 n = newN;
141
142 qsort(times,n,sizeof(times[0]),comdoub);
143 double iqr = qs(times,n,&q1,&q2,&q3);
144 rangeMin= (q1-(1.5*iqr));
145 rangeMax = (q3+(1.5*iqr));
146 }
147
148 /* calculate min/max and mean */
149 double minTime = times[0];
150 double maxTime = times[0];
151 double meanTime = times[0];
152 for(int i=1;i<n;i++) {
153 if(minTime>times[i]) minTime=times[i];
154 if(maxTime<times[i]) maxTime=times[i];
155 meanTime+=times[i];
156 }
157 meanTime /= n;
158
159 /* caculate standard deviation */
160 double sd = 0;
161 for(int i=0;i<n;i++) {
162#if U_DEBUG
163 printf(" %d: %.9f\n", i, times[i]);
164#endif
165 sd += (times[i]-meanTime)*(times[i]-meanTime);
166 }
167 sd = sqrt(sd/(n-1));
168
169#if U_DEBUG
170 printf("sd: %.9f, mean: %.9f\n", sd, meanTime);
171 printf("min: %.9f, q1=%.9f, q2=%.9f, q3=%.9f, max=%.9f, n=%d\n", minTime,q1,q2,q3,maxTime, n);
172 printf("iqr/sd = %.9f\n", iqr/sd);
173#endif
174
175 /* 1.960 = z sub 0.025 */
176 *marginOfError = 1.960 * (sd/sqrt(n));
177 /*printf("Margin of Error = %.4f (95%% confidence)\n", me);*/
178
179 return meanTime;
180}
181
182UBool calcSieveTime = FALSE;
183double meanSieveTime = 0.0;
184double meanSieveME = 0.0;
185
186U_CAPI double uprv_getSieveTime(double *marginOfError) {
187 if(calcSieveTime==FALSE) {
188#define SAMPLES 50
189 double times[SAMPLES];
190
191 for(int i=0;i<SAMPLES;i++) {
192 times[i] = uprv_calcSieveTime();
193#if U_DEBUG
194 printf("#%d/%d: %.9f\n", i,SAMPLES, times[i]);
195#endif
196 }
197
198 meanSieveTime = uprv_getMeanTime(times, SAMPLES,&meanSieveME);
199 calcSieveTime=TRUE;
200 }
201 if(marginOfError!=NULL) {
202 *marginOfError = meanSieveME;
203 }
204 return meanSieveTime;
205}