WWDC 2018:建立自定義的 Instrument

Instruments 自 2010 年發佈以後,一直不溫不火,去年也沒有任何更新值得去關注。但在一年的沉澱後,Instruments 團隊在今年終於有了個能夠使人期待的發佈。本文是針對 Session 410:Creating Custom Instruments 的解讀。express

Instruments 10

Instruments 是一款強大且靈活的性能分析工具,集成在 Xcode 的開發者工具集中。咱們可以用不一樣的 Instrument 來分析測試各類各樣的性能問題,好比 Leaks 來查內存泄漏問題,Time Profiler 來分析 App 的頁面卡頓問題等等。那麼今年蘋果對 Instruments 作了哪些更新呢?從官方的 Xcode 10 Release Notes 裏咱們能夠看到有這幾點:json

  • 開發者可以根據不一樣需求,靈活快速地基於 os_signpost 建立和發佈屬於本身的 Instrument;
  • Instruments 可以自動展現你代碼裏經過 OSLog signposts 標記的數據;
  • System Trace 裏爲線程分析新增了一個圖像模式;
  • 因爲 Instrument 10 中全部的自定義工具都會基於 os_signpost 來完成,本來基於 dtrace 的自定義 Instrument 將不被繼續支持。

其中最重要的一點即是自定義本身的 Instrument 了,雖然以往的版本中也能夠根據本身的須要去建立,但步驟麻煩且圖形化支持簡陋,而且由於數據採集是基於 DTrace 的,致使真機上並不可以使用,蘋果自身也並不鼓勵你們去作這個自定義。但 Instruments 10 針對這點此次可謂下了苦功——全新基於 os signpost 的架構可以支持全部平臺,『標準界面(Standard UI)』『分析核心(Analysis Core)』 使得自定義 Instruments 變得更加靈活並且便利。這個 Session 圍繞如何建立一個自定義的組件,分爲如下四個大部分展開:swift

  • 爲何要建立自定義的工具
  • Instruments 10 的架構體系
  • Instruments 自定義工具的初級、中級以及高級應用
  • 自定義工具的最佳實踐

其中將會涉及到一些關於專家系統(Expert System)CLIPS 語言的知識,若是有興趣的話,能夠先了解下。本文相對於 App 端開發者,可能會更適合一些測試人員,尤爲是對性能測試方面比較感興趣的同窗。緩存

爲何要建立自定義的工具

咱們都知道 Instruments 中已經內置不少方便好用的工具了,這些工具蘋果已經經過文檔模板建立好並集成在 Instruments 的啓動選擇界面裏。好比上文中提到的 Leaks 和 Time Profiler 相信不少人都有使用過,下圖的就是 Instruments 10 的啓動界面,與之前版本差異不大。 網絡

可是這些內置工具的使用其實很大程度上是基於咱們對本身代碼的充分了解,那麼如何讓不懂這部分代碼的人也可以很快了解 App 的運行數據呢,好比測試 App 的網絡層性能數據?這時候,一個良好的 Instruments 自定義工具或許就是那個答案,它可以出色地描述 App 運行狀況。另外,若是想爲內置的 Instruments 工具換個界面,或者系統提供的工具不夠用了,這些問題也可以經過建立自定義 Instruments 工具來獲得解決。

Instruments 10 的架構體系

架構的演變

介紹 Instrument 10 的架構以前,咱們先回顧下以往蘋果是怎麼維護 Instruments 組件的。 數據結構

最先一個版本的 Instruments 拖拽不一樣的 Library 到 Instruments 點擊 Record 的後即可以執行一系列的性能工具,但這些基礎庫並無提供良好的方式來繼續更新維護。早期蘋果經過繼承現有的工具完成迭代,但每一個工具都有本身的數據記錄和分析模式,他們不得不設計一個自定義的存儲機制來獲取追蹤到的數據,而後再設計一個自定義的界面來整合其餘新增的應用。這種方式隨着不斷地迭代,維護成本愈來愈高,每添加一個新的功能,就必需要修改以前最原始的那幾個工具庫,這樣在舊的架構上完成自定義 Instrument 的將會變得極其痛苦,最終蘋果放棄了舊的架構,從而也纔有瞭如今的 Instruments 10。
有了前車可鑑,蘋果在新的架構設計上就考慮到了建立新的 Instrument 怎麼纔可以更易維護的問題。全新的 Instruments 架構分爲 『標準界面(Standard UI)』『分析核心(Analysis Core)』 兩個標準組件,兩者分工不一樣但卻緊密鏈接。『標準界面』組件負責用戶交互,而『分析核心』負責數據存儲和統計分析。如今 Instruments 10 中的工具庫已經都是基於這個所建立,咱們甚至徹底能夠本身基於這兩個標準組件作一個與蘋果內置工具如出一轍的東西。

界面介紹

從上圖能夠看出,Instruments 10 的界面變化並不大,與以往的版本結構差很少。但正如前面提到的,架構變化使得如今的界面數據都將由『分析核心』提供,咱們有必要來了解下其數據結構是怎麼設計的。下圖就是一張數據表的格式。
『分析核心』以表的形式將數據傳遞給『標準界面』,而這些表能夠經過一個簡單的 Table Schema 定義。Table Schema 就和咱們 OC 或者 Swift 中的類同樣,描述了這個 Table 是什麼。也正是出於這種設計,咱們接下來纔可以使用 Table Schema 來完成自定義 Instrument 的建立。

Instruments 自定義工具的初級、中級以及高級應用

初級應用

有了足夠的理論知識後,咱們能夠嘗試下簡單的自定義工具建立了。 架構

Instruments 10 建立自定義工具和建立工程的步驟幾乎同樣,只是最後 Project 模板須要切換到 macOS 欄下,選擇 Instruments Package,並填寫好工程名等信息便可。
工程建立完成後,在左側導航中已經自動生成了一個後綴爲 .instrpkg 的 XML 文件,全部的配置都會在這個 XML 文件中完成,其中默認已經幫我生成了包含一些基礎信息。接着咱們要作的就是按照咱們的須要去寫這個配置文檔了。

一、導入須要使用的 Schemaapp

<!-- MARK: 導入你須要使用的 schema -->
    <import-schema>tick</import-schema>
複製代碼

二、完成 Instrument 的『標準界面』和『分析核心』配置ide

<!-- MARK: 導入你須要使用的 schema -->
    <import-schema>tick</import-schema>
    <instrument>
        <!-- MARK: 這個 Instrument 的基本信息 -->
        <id>com.Parsifal.TicksDemo</id>
        <title>Ticks</title>
        <category>Behavior</category>
        <purpose>Instrument drawing ticks every 100ms</purpose>
        <icon>Generic</icon>
        
        <!-- MARK: 描述的表數據,將會由 分析核心 最終完成存儲和解析提供給 標準界面 模塊 -->
        <create-table>
            <id>tick-table</id>
            <!-- 定義了每列的數據 -->
            <schema-ref>tick</schema-ref>
        </create-table>
        
        <!-- MARK: 圖形視圖上面展現(可選) -->
        <graph>
            <title>Ticks</title>
            <lane>
                <title>Lane</title>
                <!-- 這裏就是上面你定義的 table id-->
                <table-ref>tick-table</table-ref>
                <plot>
                    <value-from>time</value-from>
                </plot>
            </lane>
        </graph>
        
        <!-- MARK: 這裏描述你須要展現在詳情視圖的數據 -->
        <list>
            <title>Ticks</title>
            <!-- 這裏就是上面你定義的 table id-->
            <table-ref>tick-table</table-ref>
            <column>time</column>
        </list>
    </instrument>
複製代碼

至此咱們便已經完成了全部的編碼工做了,在編寫過程當中,咱們還會發現蘋果爲咱們準備了不少代碼片斷,來幫助完成這些配置,而且編譯期間還會對代碼進行檢查,報出的錯誤信息也很方便咱們對其進行調試。編譯運行後,在彈出的 Instruments 選擇窗口裏選擇 Blank 就能夠在測試界面的 Library 中發現咱們本身定義的工具了,直接拖入 Instruments 裏就可以像使用其餘內置工具同樣運行。 函數

另外,咱們還可以在 Instruments -> Preferences -> Packages 裏找到咱們生成的自定義工具包。

中級應用

這一部分咱們會介紹一些『標準界面』和『分析中心』裏更詳細的內容。

標準界面

『標準界面』模塊裏爲咱們提供了不少簡單又好用的元素,使用這些元素可以讓咱們建立出很是酷炫又實用的 Instruments 工具。接下來列舉一些經常使用的元素進行介紹,更多的元素還待蘋果正式發佈 Instruments 10 後你們一塊兒探索。

圖形通道面板

  • <plot>:爲圖形視圖上面劃出一個單獨的數據通道,須要提供一個值來定位縱列,如咱們 Ticks 例子中的 time;
  • <plot-template>:這個和 plot 差很少,區別在於它會自動爲每一個 instance-by 值建立一個數據通道;
  • <histogram>:爲給定的時間片斷生成柱狀圖,如 System Trace 組件中使用的那樣;

詳情面板

  • <list>:建立一個列表,常見的各類內置工具都會有的;
  • <aggregation>:建立一個總計視圖,統計總和和平均數等,使用這個元素的時候,縱列就是各類函數了,如 sumaveragecount等,另外這個元素還有個 hierarchy 屬性,可以爲不一樣的縱列設置外輪廓,很是適合於大量數據的展現;
  • <calltree>:這個就顧名思義了,調用棧的視圖;
  • <narrative>:展現一個描述工程類型(engineering type)的視圖;

分析核心

這一部分咱們首先會重點談談『分析核心』是如何收集數據和處理數據的,這一過程主要包含如下三個步驟。而後會介紹一些『分析核心』中的相關概念以助於咱們在配置表中使用它們。

一、簡化

在開始測試記錄以前,『分析核心』會先處理咱們配置好的各類表而且爲其申請存儲空間,有相同的 Schema 、屬性而且定義爲相同數據的表將會被映射爲同一個 store。

二、搜索

接着每一個 store 將會開始嘗試尋找數據的提供者。

有時候可以數據流直接找到。
但有時候須要使用 Modeler 進行合成,Modeler 能夠要求他們本身的輸入信號,而這些輸入信號也可以被做爲 Modeler 的輸出信號或者經過數據流被直接記錄。

三、優化

當咱們從各個 store 中獲取到數據源後,在『分析核心』中就開始了一項稱爲『Binding Solution』的工做,第三步就是優化這個工做流。

上圖展現了 Instruments 的這一工做流程,其中 Thread Narrative 即是它的『Binding Solution』。

一些重要的概念:

Binding Solution:Instruments 裏是經過 Thread Narrative 實現的,它有如下兩個有點

  • trace-wide;
  • Instruments 會在咱們將工具拖入測試界面的時候,開始計算尋找最佳可能的記錄方案來最小化在目標上的影響;

Schemas:咱們建立表的時候就必需要指定一個 Schema,好比咱們第一個 Demo 中的 tick

  • 目前 Instruments 裏已經定義有超過 100 個 Schema 供咱們導入使用了;
  • 包含在 Instruments 包中;
  • 能夠經過編譯設置連接其餘的 Instruments 包,在編譯期會進行類型校驗;
  • 提供了不一樣的構建模塊;

Modelers:前面提到過,Modeler 能夠幫助咱們合成不一樣的數據,關於它的有如下幾個經常使用的元素可在 XML 配置文件中使用。

  • <modeler>:建立一個 Modeler,幫助咱們作數據類型轉換的工做;
  • <point-schema>:定義一個能夠用來存儲點(無時間片斷,即某個時間點的數據)的 schema;
  • <interval-schema>:定義一個能夠用來存儲定距數據(有時間片斷,一段時間內的數據)的 schema;

PS:Modelers 實際上是一個由 CLIPS 編寫,很是強大並且高級的小型專家系統(Expert System)。它能夠指定本身須要哪些輸入信號來告知 Binding Solution 怎麼完成剩下數據圖形的填充工做。關於這一部分咱們將會在「高級應用」裏詳細說明。

最後,具有定義一個 schema 的能力是很重要的。今年新發布的 OS signpost API 賦予了咱們一個很棒的把數據導入到 Instruments 中的方式,並且蘋果爲咱們建立了一些快捷方式來使用它,好比在 XML 配置表中敲下 <os-signpost-interval-schema> 元素,就會自動生成以下代碼片斷。

<os-signpost-interval-schema>:定義了一個存儲定距數據的 schema,並且數據由 os_signpost API 提供。這就意味着咱們能夠代碼的任意地方使用 os_signpost API 來將咱們須要被測試的數據直接導入到 Instruments 中。在建立這個元素的時候, Xcode 會自動生成相關的代碼片斷以幫助咱們來完成 Modeler 的建立。 這個 API 和 os_signpost 結合使用起來就以下:

//使用這個 os_signpost 能夠再咱們代碼的任意地方將你的數據傳遞給 Instruments,但必須記得 begin 和 end 成對使用
os_signpost(.begin, log: parsingLog, name: "Parsing", "Parsing started SIZE:%ld", data.count)

// Decode the JSON we just downloaded

let result = try jsonDecoder.decode(Trail.self, from: data)

os_signpost(.end, log: parsingLog, name: "Parsing", "Parsing finished")
複製代碼
<!-- MARK: 使用這個元素就能建立從 os_signpost 獲取數據的 schema -->
<os-signpost-interval-schema>

<id>json-parse</id>

<title>Image Download</title>

<subsystem>"com.apple.trailblazer"</subsystem>

<category>"Networking"</category>

<name>」Parsing"</name>

<start-pattern>
<!-- MARK: 這裏根據咱們設置好的條件輸出信息 -->
<message>"Parsing started SIZE:" ?data-size</message>

</start-pattern>

<column>
<!-- MARK: Engineering Type 對應的助記詞 -->
<mnemonic>data-size</mnemonic>

<title>JSON Data Size</title>
<!-- MARK: 填寫的是 Engineering Type 裏定義的數據類型,好比這邊看的是內存相關的,就會有 size-in-bytes -->
<type>size-in-bytes</type>
<!-- MARK: 由 CLIPS 語言編寫的表達式做爲這個列的值 -->
<expression>?data-size</expression>

</column>

</os-signpost-interval-schema>
複製代碼

在中級這一部分,蘋果還爲咱們演示了一個 os_signpost API 使用示例。該示例中對一個展現圖片的列表頁作了圖片測試,監控了每個 cell 圖片的下載狀況。因爲涉及到的知識點上面都已經描述過了,具體示例的完成過程這邊就再也不贅述,相信經過視頻你們能看得更直觀。其中演示過程當中有提到幾點比較值得注意的,這裏重點抽出來講明下。

Instrument Inspector:若是有查看數據存儲、Modeler 和 Schema 需求的話(調試咱們自定義工具的時候可能就會用到),這個功能就可以知足你,在 『Instrument-> Instrument Inspector』裏或者 『cmd+I』 就能打開。

高級應用

這一部分將會着重介紹咱們怎麼去建立和定義 Modelers,而且簡單介紹下怎麼用 CLIPS 搭建基本的專家系統。

探祕 Modeler 的內部世界

從概念上說,Modeler 是在 Instruments 中是接受一系列輸入數據並轉化產生輸出數據的一個簡單機器。Modeler 的輸入數據每每是按時間排序的。當咱們把不一樣的輸入數據表給 Modeler 時,這些數據將會先被按時間排序而後合併進一個時間排序隊列裏。時間隊列將會依次把數據再傳遞給 Modeler 的工做內存,Modeler 就會根據工做內存的進展推理要產生什麼樣的數據並寫入到輸出表中。

咱們經過一個簡單的例子來探祕 Modeler 世界。咱們模擬這樣一種狀況,個人代碼裏有部分危險的操做容易觸發程序問題,咱們的目標就是在程序出現問題的時候,找到是哪一個操做致使的。那麼咱們能夠定義下圖中的三個 schema,前兩個做爲輸入項,最後一個是輸出項。

將這個流程,咱們已一個更加形象直觀的時序圖來展現,其中虛線表明着 Modeler 本身的時鐘:

其中,圖上我按照時間順序,標註除了 4 個值得注意的節點:

(1)這時的 App 出於正常運行狀態,沒有任何數據傳輸給 Modeler 的工做內存中,Modeler 的時鐘並無開始走;

(2)此時虛線到達咱們的第一個 input schema 觸發的節點(開始有危險操做的節點),在這裏 Modeler 的工做內存中正式開始接收到數據,Modeler 的時鐘從這個點開始計時。

(3)這是第二個 input schema 的觸發節點(咱們 App 出現問題的節點)。這裏值得一提的是,Modeler 是很機智的,它有本身的邏輯,它能區分出在這個時間節點以前的危險操做數據意義不大,而這個節點開始到 app-on-fire 這個節點結束前的數據纔是咱們所須要的。

(4)到這最後一個節點,全部的輸入數據都已經傳輸完畢了,Modeler 的時鐘與這些輸入數據沒有交集, 它推斷出這些輸入數據已經再也不被須要了,於是把它們從工做內存裏移除而且產生最終的輸出數據

能夠回顧整個過程,能夠總結出兩點:

  • Modeler 的時鐘起始時間老是第一個輸入數據觸發的時間
  • 只有與 Modeler 當前時鐘有交集的輸入數據纔會被 Modeler 保留在工做內存

這樣一種機制可以幫助咱們更清晰地定位到問題的所在,而不被那些無心義的舊數據干擾。這樣一種機制是怎麼實現的呢?答案就是咱們接下來要說明的 『生產系統(Production System)』

生產系統

Modeler 中對『工做內存(Working Memory)』的邏輯支持是來自咱們定義的 『生產系統』。『生產系統』能夠由一系列的 『規則(Rules)』 來生成,它在『工做內存』中爲 facts(CLIPS 語言中的專業術語,能夠理解爲字面意思事實,推理獲得的事實) 服務。『規則』由三部分組成—— LHS => RHS ,左邊部分 + 操做符(=>)+ 右邊部分。左邊部分是一個在『工做內存』中激活規則的條件,右邊部分則是激活後要執行的行爲。右邊的行爲包含爲輸出的數據表建立新的一行,也能夠是在建模時推斷出一個新的『fact』到『工做內存(Working Memory)』裏。結合以前上面的時序圖,咱們能夠想到『facts』 來源於兩個地方。一個是咱們看到的數據輸入表,這些是根據『規則』自動推理出的。另外一個能夠是來自於右邊部分的行爲,這些是經過 CLIPSassert 命令主動推理的。若是咱們打算建立咱們本身的『facts』,CLIPS 提供了 fact 模板,模板容許爲『fact』提供數據結構和作一些基礎類型的檢查。接下來就是介紹怎麼來定義規則了。

規則和 CLIPS

咱們可使用 CLIPS 語言定義一些規則。先回顧下上面那個例子的時序咱們是怎麼經過 CLIPS 設置規則實現的:

(defrule MODELER::found-cause//規則名
    //LHS,左邊部分指定規則激活的條件
    (playing-with-matches (start-time ?t1) (who ?object))

    (app-on-fire (start-time ?t2))

    (test (< ?t1 ?t2))

    =>
    //RHS,右邊部分爲推理產生一個 fact
    (assert (cause-of-fire (who ?object)))

)

(defrule RECORDER::record-cause//規則名
    //LHS,左邊部分未設定激活的條件
    (app-on-fire (start-time ?start))

    (cause-of-fire (who ?object))

    (table (table-id ?t) (side append))

    (table-attribute (table-id ?t) (has schema started-a-fire))

    =>
    //RHS,右邊部分爲產生輸出數據
    (create-row ?t)

    (set-column time ?start)

    (set-column who ?object)
    
)
複製代碼

其中,record-cause 這條規則定義了,若是知足如下三個條件,則此次生產會推理出一個 『fact』並被壓入『工做內存(Working Memory)』裏。

  • 一個對象 t1 這個時間在 playing-with-matches 中產生;
  • app-on-fire 在 t2 這個時間被觸發了;
  • t1 的發生時間早於 t2;

record-cause 這條規則定義了,若是知足瞭如下四個條件:

  • App 在一些起始時間「着火」;
  • 知道「着火」的緣由和相關的對象(規則 1 裏能夠拿到);
  • 有一張綁定了 Modeler 輸出側的數據表;
  • 這張數據表關聯着咱們以前定義的 start-a-fire schema;

則在輸出數據表中建立一行數據,而且設置時間和設置『左邊部分』捕獲到的中引發「着火」的值。

經過以上兩個簡單的規則,咱們便基本上建立了最先的『專家系統(Expert System)』。使用定義好的兩條規則,就能夠用來尋找咱們 App 內存在的一些問題。或許你也已經注意到,這些規則要麼是爲 Modeler 預先設置的,要麼是爲 Recorder。CLIPS 裏把他們叫作『模塊』,而且支持把規則分組和控制規則的執行順序。好比說,若是你全部的規則都定義在了記錄模塊裏生產輸出數據表,那麼你將不會在 Modeler 模塊推斷的時候寫入任何的輸出數據。由於在 Modeler 模塊 裏的規則必須在記錄模塊裏的規則以前執行。

邏輯支持

在前面探祕 Modeler 內部世界的時候,咱們提到過邏輯支持。邏輯支持通常與純推理規則關聯在一塊兒。好比說,若是 a 和 b,那麼 c。經過咱們的『生產系統』中說,就是若是 a 和 b 不存於『工做內存』了,那麼 c 就要被自動地被回收。這樣咱們就能夠說 c 是被 a 和 b 在邏輯上支持了。這樣的一種能力對於『專家系統』將『工做內存』維持在較低的水平很重要,由於它能很好地控制資源開銷。同時,把無效的 facts 從『工做內存』裏及時移除也是很重要的。若是 a 和 b 失效了,那麼 c 也應該被移除。這樣的需求在 CLIPS 裏實現會很簡單,只要經過 logical 命令就能夠,以下面的代碼。

(defrule MODELER::found-cause
    //經過 logical 命令實現邏輯支持
    (logical (playing-with-matches (start-time ?t1) (who ?object))

    (app-on-fire (start-time ?t2))

)

    (test (< ?t1 ?t2))

    =>

    (assert (cause-of-fire (who ?object)))

)

複製代碼

最佳實踐

前面洋洋灑灑說了那麼多,最後這一部分咱們主要談一下在開發自定義 Instruments 工具時有哪些最佳實踐。

多寫一個 Instrument

這句話不是建議咱們去不斷練習寫自定義的 Instrument 工具,它說的是咱們應該把 Instrument 功能作得細粒度化。舉個例子,咱們已經有了一個自定義的 Instrument 工具,但這個工具的功能並不能知足如今的需求,咱們須要在它的基礎上去增刪一些詳情或者圖形的數據展現。這樣一種場景,咱們會有兩個方式去作,第一個在原有的基礎上繼續迭代,第二個是從新再寫一個知足咱們當前需求的 Instrument。若是選擇了第一種方案,這會致使這個 Instrument 組件變得再也不純粹,雖然功能是更多了,但相應的 Instruments 也變得更加複雜。因此蘋果會更推薦咱們用第二種方案,從新寫一個符合咱們當前需求的 Instrument。若是咱們須要組合使用不一樣的 Instrument,在 Instrument 組件庫中拖拽對應的 Instrument 到咱們的文檔中便可。若是這類組合使用場景不少,咱們也能夠用 「File -> Save As Template」 保存爲模板以供接下來使用。保存模板的將會展現在咱們 Instruments 的啓動頁面,好比內置的 Leaks、Activity Monitor 和 Time Profiler 等同樣。另外這些模板,也可以很方便的在咱們的包中複用,使用 <template> 元素便可。

實時模式很困難

實時模式指的是數據的獲取、分析、到最終經過 Instruments 的界面可以實時地被展現出來。蘋果如今很難完成這種實時交互主要有兩個緣由。第一個緣由是,實時模式的完成須要一些額外的支持,但如今蘋果並無足夠充裕的時間去作;第二個更重要的緣由即是定距型數據(Interval Data,統計學上的概念,具備間距特徵的數據,可做加減計算)。定距變量只有起始和結束這個階段完成時,才能被加到數據表中和被『分析核心』所獲取。在啓動測試記錄後,Instruments 將會收到一羣定距型變量的開區間,當定距變量沒完成閉區間時,Modeler 的時鐘並不會往前走(Modeler 裏的數據是按時間排序的)。這樣的機制就會致使了一個問題,若是某個定距變量的開閉區間拉的很長,那麼 Modeler 就會一直停滯在那兒等待。但若是這個時候用戶點擊了中止記錄按鈕,全部的開區間定距變量就會關閉,一切都會恢復正常,數據將會被填充到 Modeler 裏。應該能感受到,這是一個很很差的用戶體驗。一旦咱們遇到這種狀況時,咱們有兩個選擇。第一個選擇是配置咱們的 Instrument 使它不支持這種實時模式,這個能夠經過 <limitations> 元素實現。第二個選擇避免數據出現這種長時間的開區間,例如使用 <os-signpost-interval-schema> 替代 <interval-schema>

使用『最後 5 秒記錄模式』

當建立一個用來測試含有大量輸入數據的 Instrument 時,使用『最後 5 秒記錄模式』則是咱們目前最好的選擇。這一選項咱們能夠在 「File -> Recording Options」 裏找到。以下圖:

選擇這一模式意味着將會有一個緩存池來存儲數據,而不是實時地將數據傳輸給 Instruments。緩存池機制極大地提升了效率,在 5 秒記錄模式下甚至能把 signpost 類型數據傳輸速度提高 10 倍。這個機制相應的代價是,咱們只能看到最後 5 秒的數據。但對於大批量數據的 Instruments 而言,這依然是一個不錯的選擇。

總結

Instruments 10 提供了太多建立自定義 Instrument 的可能性了,不過這一樣須要咱們花點時間來學習掌握新一套的編寫方式。對於大多數客戶端開發者來講,或許並不會用到上面談的這部分技能,但對於測試團隊來講,這無疑爲 iOS App 的性能測試又打開了一扇窗。相信在將來的一年裏,圈子內會陸陸續續地有高質量自定義 Instrument 的產出,讓咱們一塊兒期待。

查看更多 WWDC 18 相關文章請前往 老司機x知識小集xSwiftGG WWDC 18 專題目錄

相關文章
相關標籤/搜索