5

AppleScript 文档建议使用以下代码来有效地构建列表:

set bigList to {}
set bigListRef to a reference to bigList
set numItems to 100000
set t to (time of (current date)) --Start timing operations
repeat with n from 1 to numItems
    copy n to the end of bigListRef
end
set total to (time of (current date)) - t --End timing

注意显式引用的使用。这在脚本的顶层或显式运行处理程序中运行良好,但如果您在另一个处理程序中逐字运行相同的确切代码,如下所示:

on buildList()
    set bigList to {}
    set bigListRef to a reference to bigList
    set numItems to 100000
    set t to (time of (current date)) --Start timing operations
    repeat with n from 1 to numItems
        copy n to the end of bigListRef
    end
    set total to (time of (current date)) - t --End timing
end buildList
buildList()

它中断,产生一条错误消息,“无法将 bigList 转换为类型引用”。为什么这会中断,在 run() 之外的处理程序中有效构建列表的正确方法是什么?

4

3 回答 3

1

set end of l to i似乎比copy i to end of l

on f()
    set l to {}
    repeat with i from 1 to 100000
        set end of l to i
    end repeat
    l
end f
set t to time of (current date)
set l to f()
(time of (current date)) - t

您还可以使用脚本对象:

on f()
    script s
        property l : {}
    end script
    repeat with i from 1 to 100000
        copy i to end of l of s
    end repeat
    l of s
end f
set t to time of (current date)
set l to f()
(time of (current date)) - t

100000 也超过了可以保存在已编译脚本中的项目的限制,因此如果您运行脚本并尝试将其保存为 scpt,则会收到如下错误:

文档“Untitled”无法保存为“Untitled.scpt”。

您可以将set l to f()l 放在本地处理程序中,添加set l to {}到末尾,或将脚本另存为 .applescript。

于 2013-04-01T23:28:54.727 回答
1

这是我前段时间进行的速度测试的结果和方法。请注意,每个试验的第一个结果较慢,因为该脚本之前没有编译过。

list_speed.xlsx

于 2013-04-01T23:55:39.300 回答
1

将“global bigList”添加到 buildList() 的第一行可修复编译器错误。似乎在运行处理程序中,变量默认是裸露的,并且“引用”运算符很有用。但是,在其他情况下,变量本质上已经是间接引用,并且创建另一个引用层会破坏一些东西。在这些上下文中声明全局变量会去除间接引用并允许“引用”运算符工作,但这是不必要的。只需使用默认的间接引用。

如果不清楚,那是因为我不完全了解机制。如果您对这里发生的事情有更好的了解,请在下面发表评论。

于 2013-04-02T01:22:32.973 回答