forked from rebolsource/rebol-test
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bench.r3
367 lines (367 loc) · 7.02 KB
/
bench.r3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
REBOL [
Title: "Benchmark program"
Author: "Ladislav Mecir"
Date: 5-Oct-2010/11:36:11+2:00
File: %bench.r
Purpose: "Runs several benchmarks"
]
tick-time: 0.01
time-block: func [
"Time a block."
block [block!]
precision [decimal!] "suggested value: 0.05 to 0.30"
/verbose
/local guess count start finish time result
] [
if verbose [print ["Timing a block:" mold block]]
guess: 0
count: 1
while [
start: now/precise
loop :count :block
finish: now/precise
time: to decimal! difference finish start
result: time / count
if verbose [
prin "Iterations: "
prin count
prin ". Time/iteration: "
prin result
prin " seconds.^/"
]
any [
result <= 0 (abs result - guess) / result + (tick-time / time * 4) > precision
]
] [
guess: result
if error? try [count: count * 2] [return none]
]
result
]
sieve: func [size /local flags i prime series] [
flags: make block! :size
change/dup :flags :true :size
while [not tail? :flags] [
if first :flags [
i: index? :flags
prime: :i + :i + 1
series: skip :flags (:prime * :i)
while [not tail? :series] [
change :series :false
series: skip :series :prime
]
]
flags: next :flags
]
head :flags
]
fourbang: func [
/local
ten
one
temp
] [
ten: 10.0
one: 1.0
temp: ten
temp: temp + one
temp: temp - one
temp: temp * ten
temp: temp / ten
temp: temp - one
temp: temp * ten
temp: temp + ten
temp: temp / ten
temp: temp + one
temp: temp - one
temp: temp * ten
temp: temp / ten
temp: temp - one
temp: temp * ten
temp: temp + ten
temp: temp / ten
temp: temp + one
temp: temp - one
temp: temp * ten
temp: temp / ten
temp: temp - one
temp: temp * ten
temp: temp + ten
temp: temp / ten
temp: temp + one
temp: temp - one
temp: temp * ten
temp: temp / ten
temp: temp - one
temp: temp * ten
temp: temp + ten
temp: temp / ten
]
gqf2: func [
"Gaussian quadrature formula of the second order"
func [any-function!] "function to compute a definite integral of"
a [number!] "starting point of the integration interval"
b [number!] "end point of the integration interval"
n [integer!] "number of subintervals"
/local h m sum alpha beta sqrt3 halfh
] [
h: (b - a) / n
halfh: h / 2
m: 0
sum: 0
sqrt3: 1 / (square-root 3)
alpha: a + (halfh * (1 - sqrt3))
beta: a + (halfh * (1 + sqrt3))
while [:n > :m] [
sum: :sum + (func :alpha) + (func :beta)
alpha: :alpha + :h
beta: :beta + :h
m: :m + 1
]
sum: :halfh * :sum
]
msort: func [
"Merge-sort a series in place."
a [series!]
compare [any-function!]
/local msort-do merge
] [
msort-do: func [a l /local mid b] [
either l <= 2 [
unless any [
l < 2
compare first a second a
] [
set/any 'b first a
change/only a second a
change/only next a get/any 'b
]
] [
mid: to integer! l / 2
msort-do a mid
msort-do skip a mid l - mid
merge a mid skip a mid l - mid
]
]
merge: func [
{Uses auxiliary storage, at most half the size of the sorted series.}
a la b lb /local c
] [
c: copy/part a la
until [
either (compare first b first c) [
change/only a first b
b: next b
a: next a
zero? lb: lb - 1
] [
change/only a first c
c: next c
a: next a
empty? c
]
]
change a c
]
msort-do a length? a
a
]
set-words: func [
"Get all set-words from a block"
block [block!]
/deep "also search in subblocks/parens"
/local elem words rule here
] [
words: make block! length? block
rule: either deep [[
any [
set elem set-word! (
insert tail words to word! :elem
) | here: [block! | paren!] :here into rule | skip
]
]] [[
any [
set elem set-word! (
insert tail words to word! :elem
) | skip
]
]]
parse block rule
words
]
cfor: func [
"General loop" [throw]
init [block!]
test [block!]
inc [block!]
body [block!]
] [
use set-words init reduce [
:do init
:while test head insert tail copy body inc
]
]
enum: function [
"Enumerates a block"
from [integer!]
to [integer!]
] [result] [
result: make block! to + 1 - from
cfor [i: from] [i <= to] [i: i + 1] [
insert tail result i
]
result
]
locals?: func [
"Get all locals from a spec block."
spec [block!]
/args "get only arguments"
/local locals item item-rule
] [
locals: make block! 16
item-rule: either args [[
refinement! to end (item-rule: [end skip]) |
set item any-word! (insert tail locals to word! :item) | skip
]] [[
set item any-word! (insert tail locals to word! :item) | skip
]]
parse spec [any item-rule]
locals
]
funcs: func [
{Define a function with auto local and static variables.} [throw]
spec [block!] {Help string (opt) followed by arg words with opt type and string}
init [block!] "Set-words become static variables, shallow scan"
body [block!] "Set-words become local variables, deep scan"
/local svars lvars
] [
spec: copy spec
init: copy/deep init
body: copy/deep body
svars: set-words init
lvars: set-words/deep body
unless empty? svars [
use svars reduce [reduce [init body]]
]
unless empty? lvars: exclude exclude lvars locals? spec svars [
insert any [find spec /local insert tail spec /local] lvars
]
do init
make function! reduce [spec body]
]
round-place: funcs [
x [number!]
place [integer!]
/ceiling "round up"
/floor "round down"
] [] [
scale: 10.0 ** place
x: either place <= 0 [
if (abs x) + scale - (abs x) = 0 [return x]
scale: 10.0 ** negate place
x * scale
] [
x / scale
]
r: x // 1.0
s: case [
floor [either r >= 0 [0.0] [-1.0]]
ceiling [either r > 0 [1.0] [0.0]]
r >= 0.0 [
case [
r > 0.5 [1.0]
r < 0.5 [0.0]
x // 2.0 = 0.5 [0.0]
true [1.0]
]
]
r < -0.5 [-1.0]
r > -0.5 [0.0]
x // 2.0 = -0.5 [0.0]
true [-1.0]
]
either place <= 0 [x + s - r / scale] [x + s - r * scale]
]
autoround: funcs [[catch]
x [number!] "number to round"
digits [integer!] "digits to keep"
/ceiling "round up"
/floor "round down"
] [] [
if digits < 1 [throw make error! "digits needs to be >= 1"]
if zero? x [return x]
place: round/floor/to log-10 abs x 1
if positive? 10.0 ** place - abs x [place: place - 1]
place: place - digits + 1
case [
floor [round-place/floor x place]
ceiling [round-place/ceiling x place]
true [round-place x place]
]
]
random/seed 1
use [computer precision os size flags t count result sinerad icount serf compare mcount] [
prin "Benchmark run "
prin now
prin ". Rebol "
print Rebol/version
prin "Computer: "
computer: input
prin "OS: "
os: input
precision: make decimal! ask "Precision: "
prin "Empty block: "
t: time-block [] precision
print rejoin [autoround 1 / t 3 "Hz"]
size: 8190
prin rejoin ["Eratosthenes Sieve Prime (size: " size "): "]
t: time-block [flags: sieve size] precision
count: 0
foreach flag flags [
if flag [count: count + 1]
]
print rejoin [
autoround 1 / t 3
"Hz, result: "
count
" primes"
]
prin "Four-Banger test (+,-,*,/): "
t: time-block [result: fourbang] precision
print rejoin [
autoround 1 / t 3
"Hz, result: "
result
]
icount: 10000
prin rejoin ["Integral (icount: " icount ") of sin(x) 0<=x<=pi/2: "]
sinerad: func [x] [sine (x * 180 / pi)]
t: time-block [result: gqf2 :sinerad 0 (pi / 2) icount] precision
print rejoin [
autoround 1 / t 3
"Hz, result: "
result
]
prin rejoin ["Integral (icount: " icount ") of exp(x) 0<=x<=1: "]
t: time-block [result: gqf2 :exp 0 1 icount] precision
print rejoin [
autoround 1 / t 3
"Hz, result: "
result
]
mcount: 500
prin rejoin [
"Merge Sort ("
mcount
" elements): "
]
compare: func [a b] [
return a <= b
]
b: random enum 1 mcount
t: time-block [msort copy b :compare] precision
print rejoin [
autoround 1 / t 3
"Hz"
]
]