Coder Social home page Coder Social logo

eluaprofiler's Introduction

ELuaProfiler

☁️ Easy Lua Profile ☁️

Update

2023.04.19 优化统计性能

优化ELuaProfiler统计性能,约提高到300%


2023.02.20 PerFrame模式支持柱状图


2023.02.07 支持序列化和反序列化

UE4 Console输入: eluaprofiler start 0/1 eluaprofiler stop

elprof文件会存放在Saved/ELuaProfiler/

后续优化: 流式保存PerFrame模式下的elprof文件


Supported Solutions

Solution Supported
unlua-ue4
slua-ue4 ×
slua-unity ×

Build

UE4

  1. configure Setup.bat/Setup.command
    • set src=E:\repo\ELuaProfiler\UE4\UnLua\
      set dst=E:\YourProject\Plugins\
      
  2. Run Setup.bat/Setup.command
  3. Build YourProject

Unity

待开发

Usage

ELuaMonitor

ELuaMonitor主要用于剖析Lua的CPU性能,以及内存频繁开辟引起GC的问题,编辑器界面如图:

MonitorMode

右上角为模式选择控件,目前支持三种模式

  1. PerFrame
    • 逐帧采样,并且可以按帧数前后回溯
  2. Total
    • 累计采样,统计一段时间内的开销情况,最常用。
  3. Statistics
    • 统计模式,在Total的基础上将所有节点平铺开,统计单函数的开销。

MonitorController

  1. Play
    • 中间的按钮为Play,点击Play后,如果LuaVM启动了,会立刻开始Profile。否则等待LuaVM启动,自动开始Profiler
    • 开始Profile后按钮变为暂停键,可以暂停和恢复Profile
  2. Clear
    • 最右侧为Clear按钮,点击Clear后会立刻停止Profile,并清空当前Profile数据
  3. NextFrame/PrevFrame
    • 逐帧回溯,分别为上一帧和下一帧。
  4. CurFrameIdx/TotalFrame
    • 当前帧数/总帧数
    • CurFrameIdx支持手动输入
    • 当0 < CurFrameIdx < TotalFrame,会停在CurFrameIdx这一帧
    • 否则CurFrameIdx会等于TotalFrame,并跟随TotalFrame一起增长

MonitorData

  1. TotalTIme(ms)
    • 函数从Call到Return总共消耗的时间,单位为毫秒
    • 该值会受Profiler本身开销影响,主要是Profiler取Time的开销(因为Profiler取Time必须是同步的,但比如自增函数的开销比取Time开销还小,势必会造成误差,可以控制ProfileDepth来消除)
  2. TotalTime(%)
    • 该函数调用时间开销占父节点的百分比
    • TotalTime / Parent.TotalTime
  3. SelfTime(ms)
    • 代表该函数自身的开销
    • TotalTime减去各子节点的TotalTime
  4. SelfTime(%)
    • 自身开销占自身节点的比重
    • SelfTime / SelfTime
  5. Average(ms)
    • 平均每次调用耗时
    • TotalTime / Calls
  6. Alloc(kb)
    • 函数调用期间开辟的内存,单位为kb
  7. Alloc(%)
    • 该函数开辟的内存占父节点的比重
    • Alloc / Parent.Alloc
  8. GC(kb)
    • 函数调用期间释放的内存,因为Lua的GC为步进式,所以不能准确形容当前函数释放的内存。
    • 但一级节点的Alloc - GC可以作为整个Lua的内存增量,可以用来观察代码是否有明显泄露,但具体定位还应该使用ELuaMemAnalyzer。
  9. GC(%)
    • 该函数调用期间发生的GC占父节点的比重
    • GC / Parent.GC
  10. Calls
    • 该函数被调用次数

Max Depth

Max Depth控制Profile的最大深度,最小值为1,最大值为1000(可在代码中更改),Max Depth可以有效消除Profiler的误差。从我的经验来说,Profiler的误差主要来源于Profiler的GetTime函数。而且GetTime必须是同步进行的,所以这部分误差会一直存在。考虑以下代码

function EmptyFunction()

end

function Counting()
    for i = 1, 1000 do
        EmptyFunction()
    end
end

当我们统计到Counting函数的时候,会统计到1000次EmptyFunction函数的开销。但由于EmptyFunction函数的开销过小,甚至比Profiler的GetTime函数的开销还小。所以Counting的统计势必存在很大的误差,这个时候我们可以将MaxDepth设定在Counting这一层,不再继续展开,不统计过细的分支(在这个例子中指EmptyFunction),我们就能正确地观察到Counting的性能开销。

一般我们在实战中,从1开始慢慢增加Depth,直到我们停在一个合适的地方。

排序

默认按照TotalTime降序排列,点击不同的Title会根据不同的数据进行降序排列。 目前支持以下数据的降序排列:

  1. TotalTime
  2. SelfTime
  3. Average
  4. AllocSize
  5. GCSize
  6. Count

ELuaMemAnalyzer

Snapshot

在ELuaMemAnalyzer中点击一次采样,即可生成一个SnapshotSnapshot中包含了当前时刻的内存情况,以_G为根节点。 同时Snapshot也支持逻辑运算,以方便剖析内存的泄露和增长。

Snapshot Logic Operation

Snapshot为单元进行逻辑运算,目前支持&与|或^异或运算,这三个运算配合强制GC可以很好地查找泄露。选择了一个Snapshot后,点击需要进行的操作按钮(AND、OR、XOR),然后再点击另一个Snapshot。就会对两个Snapshot进行逻辑运算,并生成一个新的Snapshot

  1. & Operation
    • 两颗Snapshot进行与运算,得到两个时刻相同的内存部分。
  2. | Operation
    • 两颗Snapshot进行或运算,得到两个时刻总的内存部分,相当于A + B
  3. ^ Operation
    • 两颗Snapshot进行异或预算,得到两个时刻的内存差异部分。
  4. Memory Leak
    • 在刚启动游戏时,或强制GC后,采样得到SnapshotA
    • 在游戏内进行游玩时,每隔5分钟采样,得到SnapshotBSnapshotCSnapshotD
    • 常驻内存 = SnapshotA & SnapshotB & SnapshotC & SnapshotD

Deviation

由于种种原因,内存统计的误差都不可避免。误差主要来自于这几方面:

  1. Lua的Intern机制
    • 由于Lua对短字符串和number采用了Intern机制,所以这部分存在重复统计。
    • 后续优化考虑做一个去除。
  2. 多重引用,比如A:{B: {D, E}, C: {D, F}},这样一颗三层的树。
    • 为了保证单独查看节点B和节点C的正确性,B = D + EC = D + F
    • 所以A = D + E + D + F,存在一定的误差。

Roadmap

1. Support slua-ue4

接入slua-ue4

2. Remote Profile

将ELuaProfiler分为Server和Client,支持真机远程Profile

3. Serialize & Deserialize

支持Profile数据的序列化和反序列化 2023.02.07实现

4. Support slua-unity

接入slua-unity,并编写Unity版本的EditorUI

5. Support unlua-unity

接入unlua-unity

6. Support xlua-unity

接入xulua-unity

eluaprofiler's People

Contributors

donghangssn avatar hugebug4ever avatar inkiu0 avatar jozhn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eluaprofiler's Issues

支持一下在lua中插桩分析性能?

想具体分析lua中某个函数的调用堆栈与耗时情况,使用perframe、total等模式都不太适合,如果能够在lua中控制开始和结束就好了。目前如果在lua中调用Console命令会崩溃

在UE4Editor-ELuaMonitor.dll!FELuaTraceInfoTree::OnHookCal调用时崩溃

GetChild时候CurNode为Null。
堆栈如下:
[内联框架] UE4Editor-ELuaMonitor.dll!TSharedPtr<...>::operator->() 行 890 C++
UE4Editor-ELuaMonitor.dll!FELuaTraceInfoTree::GetChild(const void * p, FString ID) 行 81 C++
UE4Editor-ELuaMonitor.dll!FELuaTraceInfoTree::OnHookCall(lua_State * L, const void * p, FString ID, bool IsStatistics) 行 49 C++
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.