Editor Iteration Profiler (EIP) Before diving into the details, I will start by defining what an iteration is. An iteration is a process that contains instructions that are repeated until a condition is met. Unity relies on different types of iterations.
The Editor Iteration Profiler monitors iterations that are related to the scripting side of Unity, specifically entering and exiting playmode, assembly compilation, and assembly reload.
The tool is an attempt to empower you, our users, to understand and help you solve the common question “Why does it take so long to compile my scripts/enter playmode?”. EIP accomplishes this by monitoring profiler frames and saving them in a window where you can more easily navigate through the data the profiler produces. Additionally, the data persists for the whole lifetime of the Editor (or until it’s cleared), as opposed to the Profiler, which has a limit to the number of previously stored frames.
Disclaimer: This tool is still under development and anything could change on the API side.
High-level features summary
Monitor and capture profiling data from assembly reload, assembly compilation, and enter playmode.
Export captured data or Profiler data to a number of formats such as HTML, JSON (for chrome://tracing, which is a fast flame-graph style data visualizer), CSV, and Plaintext.
Export to a special type of HTML (HTML Performance Report), which attempts to minimize the number of clicks needed to get to the important areas of the profiled data, as well as aggregate possible areas of interest which could be optimized (e.g. OnEnable calls)
How to use Compatible with 2019.3 and later. It might work with earlier versions, but it is not tested.
Place the contents in a folder in your Project’s Packages folder
Open up the project and open the window fromWindows → Analysis → Editor Iteration Profiler → Show Window
You should see a window very similar to this
The basics To enable the tool, you just need to click the Enable button in the window. The window doesn’t need to be open afterward: it will run in the background.
After an iteration happens, it will show up in the window as follows:
UI Please note that the UI might change/have changed slightly, however, the functionality should be the same.
Enable - enables the Profiler and sets it to run in Editor mode.
Flattening - attempts to reduce the number of clicks needed to get to the place that is of interest. Works by ‘collapsing’ levels which contain multiple parented items with 1 child. Useful for GUI code and Deep Profiling.
User Code - is an attempt to filter out engine code and only show code the User might be interested in.
Clear - removes recorded events and events which the EIP is looking for.
Collapse All - recursively collapses every item.
Print to Console - logs the captured data into plaintext into the console/log file.
Export… - dropdown to export captured data in various formats.
Export Profiler Data… - dropdown to choose between exporting the selected frame in the Profiler Window or exporting multiple frames, frame by frame, between 2 ranges. It will automatically export the data to a selected folder.
Search Bar - works as you would expect. Selecting an item and either pressing the F key or clearing the search will automatically expand the tree view to that item.
Exporters
After you have captured some data, you might want to export it. You can do this by clicking the Export… dropdown and choosing a format.
Hereyou can get the samples exported above for you to test out.
The Formats
Opening the HTML, you will see something similar to this:
It mostly contains the same data as the EIP Window, with the addition of the percentages. Items in square brackets “[ ]” are leaf items without any children.
The JSON format is meant to be used within Google Chrome'schrome://tracing, which works on chromium-based browsers like Google Chrome, Microsoft Edge Chromium (edge://tracing - chrome://tracing will be replaced by it if typed), Opera, etc.. It is a fast, lightweight and Editor-agnostic way to view the captured data in the flame-graph style.In this gif, we show how to load and use the file intochrome://tracing.
CSV can be used to load the data into other programs, for example. It is pretty difficult for humans to make sense of it. Also, please be aware of the ‘header’ which contains environment information in case you plan to do further processing.
Exporting Plaintext is the same as the one it is printed in the console with the “Print to Console” button. Using this, you have the option to isolate the data and not have other information which is in the Editor.log file.
TheHTML Performance Reportis based on the same structure as the regular HTML report, however, functionally it is different. The purpose of it is to distill the information into something humans would more easily understand. It basically does this by reducing the number of levels you have to click through to get to the areas of interest, where code diverges more.
The items in curly brackets “{ }” represent items that have more children, which were hidden due to the parents being under the minimum set threshold (currently a hard-coded value of 1%).
The colored items represent ‘buckets’ of similar data, which is grouped in one place for convenience. The total time of these items is not added to the original time, it’s only there to give an estimate for that iteration.
In order to get the most accurate data (especially with DeepProfile enabled),close as many Editor Windows as possible, including the EIP Window itself (it will keep working even when closed if it's Enabled).The reason is that rebuilding the Tree Hierarchy view and repainting the GUI takes time, and it will "pollute" the data you might be looking for. The more data, the more it will be polluted (Deep Profile will naturally lead to this faster). This has been mostly mitigated in0.1.2-preview(cost is still there, just delayed so it doesn't pollute the data).
When clicking the Profiler Window after clicking Enable in the EIP Window, the EIP's state will be overridden to whatever the original setting in the Profiler was
May cause unity to crash when closing it while the EIP is Enabled
Feedback In terms of feedback, we're especially looking for:
Are there any useful use-cases not covered?
Are there any workflows that are unclear or missing?
Is there anything that is unclear or that you don’t understand?
Are there any issues or unclear parts in the documentation or this post?
Troubleshooting If you encounter any problems, the simplest fix is usually to use the Clear button for the window. Another option you can try is throughWindow → Analysis → Editor Iteration Profiler → Purge Caches.
When the Type of `AlternateIcon` is set to Auto Generate, the icon will be automatically resized at build time, so there is nothing to worry about. (The maximum size is 1024px.) If you want to control it in detail, you can change the Type to Manual.
## Requirements - Unity 2020.3 or higher. - Xcode 13 or higher.
nameTranslation.txt 파일을 상대경로(파일명만)로 지정했을 때 제대로 생성하지 못하는 문제가 있어서 우회하도록 수정함.
BuildReport에서 주는 빌드파일 경로를 쓰지 않고, string.Format(@"{0}/..", Application.dataPath) 로 프로젝트 패스를 쓰도록 변경함.
해당 방식을 쓰기위해 Android 일 때만, Obfuscator의 OptionsManager.cs의 LoadAssetAtPath 함수를 아래와 같이 일부 수정했다.
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace Beebyte.Obfuscator
{
public class OptionsManager
{
....
private static Options LoadAssetAtPath(string path)
{
// [Android] nameTranslationFile Path 변경
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
{
// Custom
Options o = AssetDatabase.LoadAssetAtPath<Options>(path);
if (o == null)
{
return null;
}
// 옵션값 덮어쓰지 않도록 Clone해서 사용.
var clone_o = Object.Instantiate(o);
/// 현재 프로젝트 절대 경로(Application.dataPath/../)로 수정 반환
// 파일명(Default:nameTranslation.txt)만 추출해서 저장
string strnameTranslation = System.IO.Path.GetFileName(clone_o.nameTranslationFile);
// 현재 프로젝트 Path 적용. 절대경로값 지정
clone_o.nameTranslationFile = string.Format(@"{0}/../{1}", Application.dataPath, strnameTranslation);
return clone_o;
}
// [iOS] 기존 방식
else
{
// Original
return AssetDatabase.LoadAssetAtPath<Options>(path);
}
}
....
}
}
----
Obfuscator에 난독화 기능을 쓸 때,
난독화 전/후 Naming 매칭 리스트를 뽑아주는 옵션이 있다.(아래 스샷 참조)
ObfuscatorOptions.asset
체크하면 기본 파일명이 nameTranslation.txt인데 빌드 할 때마다 덮어버리니 관리가 안돼서 빌드마다 별도로 만들어질 수 있도록 PostProcess로 파일명을 Rename 하도록 처리했다.
아래 소스를 프로젝트에 추가하면,
[Android] namteTranslation.txt 파일을 빌드 파일명에 매칭해서 자동으로 변경해준다.
ex) 빌드 파일명 : abc_v1.0.0.apk
변경되는 파일명 : abc_v1.0.0.apk_ namteTranslation.txt
[iOS] iOS는 빌드 시점에 파일명이 지정되는게 아니라서 별도의 조합으로 진행되도록 했다.
WARNING:/Users/{UserAccount}/.gradle/caches/transforms-2/files-2.1/ea30c3c071cd48c926311878c13eb08b/jetified-unity-classes.jar: D8: Expected stack map table for method with non-linear control flow.
그래서 아래 위치의 gradle cache 하위 있는 것들을 모두 삭제하고 새로 빌드를 실행해서 잘 돌아가는 것을 확인했다.