gpt4 book ai didi

performance - 如何在Rebol中对一系列功能进行基准比较?

转载 作者:行者123 更新时间:2023-12-04 22:48:19 27 4
gpt4 key购买 nike

我最近询问了fastest/most efficient way to count newlines in Rebol,我现在需要确定在给定情况下哪种方法最好。

一些示例方案:短文本,换行更少;短文本,许多换行符;中/长文本,许多换行符(代码);中/长文本,换行符较少(文章)。

我有一些不确定性:如果我一个接一个地跑,第二个测试会被第一个测试污染吗?对于不同的场景(优化),要求不同的功能将有多大的差异,而对于所有功能,一个功能都可以满足(便利)?我需要两个Rebol 2.7.8和Rebol 3的基准。

这是我要测试的一组特定功能,尽管也可以使用更通用的答案:

reduce [
"@rebolek"
func [text [string!] /local i][
parse text [(i: 1) any [thru newline (++ i)]] i
]

"@darius"
func [text [string!] /local tmp][
tmp: sort join text "^/"
1 + subtract index? find/last tmp "^/" index? find tmp "^/"
]

"@endo64"
func [text [string!]][
(length? text) - (length? remove-each v text [v = #"^/"])
]

"@BrianH"
function [text [string!]] [
i: 1
find-all text newline [++ i]
i
]

"@MaxV"
func [text [string!]][
write %.mytext text
text: read/lines %.mytext
delete %.mytext
length? text
]
]

最佳答案

在REBOL(R2和R3)中进行配置分析所面临的挑战是三方面的。定时,循环和内存使用。

定时:

在某些操作系统上,默认计时不精确(例如Windows)。这可以通过创建更大的环路来大大缓解,该环路基本上可以将测试扩展到可接受的时序裕度。您还可以创建更好的计时器,例如我为Windows构建的chrono lib(chrono-lib.r)。

它还包括一个延时功能,使测试块变得容易(基本上是针对Windows的更精确的“ DT”)。

循环播放:

这是很明显的事情,当您花费时间来消除某些OS /多任务处理开销时,可以多次运行代码并将重复次数除以得到平均值。这通常足以获得一个好主意。

但是,循环本身本身是相当昂贵的。迭代函数具有其自己不可忽略的开销。因此,在循环某些代码之前,请确保您使用的循环是最佳的,尤其要确保您使用的是本机迭代器函数,因为循环的最终结果可能比您要分析的代码慢。在R2中,在大多数情况下,FOREACH和LOOP是更快的循环。在开始循环之前,FOREACH的绑定开销很小,但是在我的广泛测试中,这几乎没有影响,因为它只发生一次,与运行几秒钟无关。

在R3中,由于R2中的某些mezz循环已成为本机,因此迭代器函子的速度有所提高,因此您必须检查它们以查看。

记忆:

这是事情变得难以预测的地方。 REBOLs GC在进行性能分析时相当麻烦。它不仅速度很慢,而且还是不可预测的,实际上无法进行优化,并且随着REBOL内存占用量的增加而减慢速度(实际上,这超出了人们的想象)。

减多少让我们来看看:

这是我必须基准测试内存使用和执行速度的脚本。它生成的图形可以向我显示一个彼此之间的关系。它具有关闭垃圾收集器的一个选项...,您将看到它如何影响分析...带有和不带有该图形的图形都非常清楚:

rebol [
title: "profiling tests with graphics"
author: "Maxim Olivier-Adlhoch"
purpose: "given a few metrics and code blocks, will plot out the time and memory use for each repetition."
]

;----
; test metrics
loops: 2000
repetitions: 500

;----
; test options
turn-off-garbage-collector?: false

;----
; output gfx prefs
mem-color: red
time-color: sky
bg-color: black
gfx-size: 600x400
margins: 100x100
lw: 2 ; line-width
label-color: white * .85
border-color: gray * 0.5
slices: 10 ; how many labels on the edges of the graphics.


;----
; globals
plot-data: []

;----
;- functions
platform: does [
select [
1 AMIGA
2 OSX
3 WIN32
4 LINUX
] system/version/4
]


;----
; make sure timer resolution is decent on all platforms
;----
either ( platform = 'WIN32 ) [
either exists? %libs/windows-chrono.r [
do %libs/windows-chrono.r
][
ask "download and save windows-chrono from rebol.org ? ^/^/ * press ENTER to confirm^/ * press ESCAPE to halt."
make-dir %libs/
write %libs/windows-chrono.r read http://www.rebol.org/download-a-script.r?script-name=windows-chrono.r
print "windows chrono downloaded"
]
][
; on other platforms, the OS timer resolution tends to be better, we can just use delta-time
time-lapse: :delta-time
]
; time-lapse: :delta-time


;----
; TEST CODE INITIALISATIONS
blk: make block! repetitions

print "===================="
print "running tests"

;----
; SETUP TEST OPTION(S)
if turn-off-garbage-collector? [
recycle/off
]

;--------------------------------------------
; PERFORM AND PLOT TESTS
;--------------------------------------------
repeat i repetitions [
;--------------------------------------------
; PUT YOUR LOOP INIT CODE HERE:
;--------------------------------------------
tmp: last append/only blk copy []
time: time-lapse [

loop loops [
;--------------------------------------------
; PUT YOUR TEST CODE HERE:
;--------------------------------------------
; here we just accumulate RAM...
append tmp make string! 1000
]
]
memory: stats
append plot-data reduce [ time memory]
prin "."
]


;-------------------------
; extract plot data scale
;-------------------------
time-x: 0:00
stat-y: 0

foreach [time stat] plot-data [
time-x: max time-x time
stat-y: max stat-y stat
]


time-scale: (gfx-size/y / to-decimal time-x )
mem-scale: gfx-size/y / stat-y

print ""
?? time-scale
?? mem-scale

;-------------------------
; build gfx
;-------------------------

;-------
; lines
i: 0
mem-line: compose [line-width lw pen (mem-color ) line () ]
time-line: compose [line-width lw pen (time-color ) line () ]
foreach [time ram] plot-data [
time: to-decimal time
;?? time
;print time * time-scale

append mem-line margins + to-pair reduce [ x: to-integer (i / (repetitions - 1) * gfx-size/x) to-integer ( ram * mem-scale )]
append time-line margins + to-pair reduce [ x to-integer ( time * time-scale )]
i: i + 1
]

;------
;scales
scale-drw: compose [
line-width 1
pen (border-color) box (margins) (margins + gfx-size)
]

repeat i (slices + 1) [
ii: i - 1
append scale-drw reduce [
'pen mem-color
'text margins + to-pair reduce [ -50 (gfx-size/y - (ii / slices * gfx-size/y ) ) - 5 ]
rejoin [ to-string round/to (ii / slices * stat-y / 1'000'000) 0.01 " MB" ]

'pen time-color
'text margins + to-pair reduce [ gfx-size/x (gfx-size/y - (ii / slices * gfx-size/y ) ) - 5 ]
rejoin [ to-string round/to (1000 * ii / slices * to-decimal time-x) 0.1 "ms" ]

'pen border-color
'text margins + to-pair reduce [ ((ii / slices * gfx-size/x ) ) gfx-size/y + 10 ]
rejoin [ to-string to-integer( ii / slices * repetitions) ]
]
]

view layout compose/deep [
box (margins * 2 + gfx-size) bg-color effect [draw [
translate (0x1 * (margins * 2 + gfx-size)) scale 1 -1.0 (mem-line) (time-line)
reset-matrix
(scale-drw)
]]
]


随意复制和编辑此脚本,这是一种非常简单的绘图机制……我敢肯定,您可以添加其他曲线(例如正在测试的函数的输出值的曲线)。

在此脚本的顶部,您可以看到有一个禁用GC的选项...在此循环的测试代码中,我们只是分配RAM,以查看GC如何影响整体性能。

这是启用GC的运行:


您会看到执行受到阻碍,因为GC一直在监视并中断该过程。

随着RAM的增加(红线),执行速度会不断降低。请注意,所有块都是预先分配的,因此这不是由于内部存储器复制引起的。

这是禁用GC的运行:


您可以清楚地看到操作的线性度。

您在两次运行中都有不规则的跳跃是由于正常的OS多任务处理。

请注意,两个测试中的最佳速度是相同的。大约5毫秒...但是在启用GC的运行中,平均值只会越来越差。

因此,当我测试任何代码时,我总是将GC关闭,除非该代码生成的立即内存使该任务很快耗尽了内存。或者,您可以在代码中的关键点进行回收/关闭回收/打开,以减轻方程式中的这一部分问题。当调用recycle / on时,如果超出阈值,它将立即进行清理。

请注意,内存分配的复杂性会影响GC。这不仅会影响RAM的数量,还会影响正在构建的值的数量,这将带来很大的后果。使用上面的探查器,您可以构建指数级缓慢的算法,当这些算法开始实时运行时,仅300MB就几乎无法使用。

绑定并创建许多复杂的对象是一件事,它将彻底破坏rebol中任何速度的假装。如果要创建大型数据集,使用块层次结构而不是对象层次结构确实更好。

希望以上脚本能帮助您介绍一些要测试的内容。

关于performance - 如何在Rebol中对一系列功能进行基准比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14988163/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com