2013-04-01 42 views
5

tài liệu AppleScript cho thấy đoạn mã sau để xây dựng một cách hiệu quả một danh sách:Làm thế nào để bạn xây dựng một danh sách hiệu quả trong một trình xử lý trong 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 

Lưu ý việc sử dụng một tài liệu tham khảo rõ ràng. Đây hoạt động tốt ở cấp cao nhất của một kịch bản hay trong một handler chạy rõ ràng, nhưng nếu bạn chạy mã chính xác cùng nguyên văn trong xử lý khác như vậy:

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() 

nó phá vỡ, năng suất một thông báo lỗi nói rằng, "Can 't làm bigList thành tham chiếu kiểu. " Tại sao điều này phá vỡ, và cách chính xác để xây dựng một danh sách hiệu quả trong một trình xử lý khác với run() là gì?

+1

Sự cố tương tự này gặp phải (không có câu trả lời thỏa đáng) ở đây: http://stackoverflow.com/questions/3569847/why-cant-applescript-make-firstvalue-of-hash-into-type-reference-in-this -test-c? rq = 1 – 108

+0

Và hữu ích hơn là: http://stackoverflow.com/questions/15777321/why-in-applescript-cant-you-declare-references-to-variables-local-to-handlers – 108

Trả lời

1

set end of l to i có vẻ là nhanh hơn so vớ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 

Bạn cũng có thể sử dụng một đối tượng kịch bản:

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 cũng là so với limit of items that can be saved in compiled scripts, do đó bạn sẽ nhận được một lỗi như thế này nếu bạn chạy tập lệnh và cố gắng lưu tập lệnh dưới dạng scpt:

Tài liệu “Chưa có tiêu đề” không thể được lưu dưới dạng "Untitled.scpt".

Bạn có thể đặt set l to f() bên trong một handler để l là địa phương, thêm set l to {} đến cùng, hoặc lưu kịch bản như .applescript.

1

Dưới đây là các kết quả và phương pháp kiểm tra tốc độ tôi đã làm trước đây. Lưu ý rằng kết quả đầu tiên trong mỗi lần thử nghiệm chậm hơn vì tập lệnh chưa được biên dịch trước đó.

list_speed.xlsx

1

Thêm "toàn cầu bigList" vào dòng đầu tiên của BuildList() sửa lỗi biên dịch. Dường như trong trình xử lý chạy, các biến được mặc định theo mặc định, và toán tử "tham chiếu đến" là hữu ích. Tuy nhiên, trong các ngữ cảnh khác, các biến đã là các tham chiếu cơ bản gián tiếp và tạo một lớp tham chiếu khác phá vỡ các công cụ. Việc khai báo một biến toàn cục trong các ngữ cảnh này sẽ loại bỏ tham chiếu gián tiếp và cho phép toán tử "tham chiếu đến" hoạt động, nhưng điều này là không cần thiết. Chỉ cần sử dụng tham chiếu gián tiếp mặc định.

Nếu điều này không rõ ràng, đó là vì tôi không hoàn toàn hiểu cơ chế. Nếu bạn hiểu rõ hơn về những gì đang xảy ra ở đây, vui lòng góp ý dưới đây.