CLI to profile compilation time of Swift project
MIT License
Command line utility to profile compilation time of Swift project.
This tool is developed in working time for Cookpad.
gem install xcprofiler
xcprofiler is tested on latest Ruby 2.3/2.4.
Add -Xfrontend -debug-time-function-bodies
build flags in Build Settings
-> Other Swift Flags
section of your Xcode project.
Build your project
Execute xcprofiler
$ xcprofiler [PRODUCT_NAME or ACTIVITY_LOG_PATH] [options]
xcprofiler
searches the latest build log on your DerivedData directory.
You can also specify the .xcactivitylog
.
$ xcprofiler MyApp
$ xcprofiler ~/Library/Developer/Xcode/DerivedData/MyApp-xxxxxxxxxxx/Logs/Build/0761C73D-3B6C-449A-BE89-6D11DAB748FE.xcactivitylog
Sample output is here
+----------------------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
| File | Line | Method name | Time(ms) |
+----------------------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
| ResultProtocol.swift | 132 | public func ==<T : ResultProtocol where T.Value : Equatable, T.Error : Equatable>(left: T, right: T) -> Bool | 14.2 |
| Result.swift | 66 | get {} | 13.1 |
| Result.swift | 78 | public static func error(_ message: String? = default, function: String = #function, file: String = #file, line: Int = #line) -> NSError | 6.3 |
| Result.swift | 69 | get {} | 2.2 |
| Result.swift | 132 | public func `try`<T>(_ function: String = #function, file: String = #file, line: Int = #line, try: (NSErrorPointer) -> T?) -> Result<T, NSError> | 1.7 |
| Result.swift | 95 | get {} | 1.4 |
| Result.swift | 21 | public init(_ value: T?, failWith: @autoclosure () -> Error) | 0.9 |
| Result.swift | 142 | public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, try: (NSErrorPointer) -> Bool) -> Result<(), NSError> | 0.9 |
| ResultProtocol.swift | 172 | @available(*, unavailable, renamed: "recover(with:)") public func recoverWith(_ result: @autoclosure () -> Self) -> Self | 0.7 |
| Result.swift | 72 | get {} | 0.6 |
| Result.swift | 75 | get {} | 0.6 |
| ResultProtocol.swift | 72 | public func recover(_ value: @autoclosure () -> Value) -> Value | 0.5 |
| ResultProtocol.swift | 111 | public func &&&<L : ResultProtocol, R : ResultProtocol where L.Error == R.Error>(left: L, right: @autoclosure () -> R) -> Result<(L.Value, R.Value), L.Error> | 0.5 |
| ResultProtocol.swift | 144 | public func !=<T : ResultProtocol where T.Value : Equatable, T.Error : Equatable>(left: T, right: T) -> Bool | 0.5 |
| ResultProtocol.swift | 92 | public func tryMap<U>(_ transform: (Value) throws -> U) -> Result<U, Error> | 0.4 |
| Result.swift | 175 | @available(*, unavailable, renamed: "success") public static func Success(_: T) -> Result<T, Error> | 0.3 |
| ResultProtocol.swift | 55 | public func mapError<Error2>(_ transform: (Error) -> Error2) -> Result<Value, Error2> | 0.3 |
| ResultProtocol.swift | 77 | public func recover(with result: @autoclosure () -> Self) -> Self | 0.3 |
| ResultProtocol.swift | 93 | (closure) | 0.3 |
| Result.swift | 31 | public init(attempt f: () throws -> T) | 0.2 |
+----------------------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
option | shorthand | description |
---|---|---|
--limit | -l | Limit for display |
--threshold | Threshold of time to display (ms) | |
--show-invalids | Show invalid location results | |
--order | -o | Sort order (default,time,file) |
--derived-data-path | Root path of DerivedData directory | |
--truncate-at | -t | Truncate the method name with specified length |
--no-unique | Show the duplicated results |
You can use reporters to output tracking logs.
require 'xcprofiler'
profiler = Xcprofiler::Profiler.by_product_name('MyApp')
profiler.reporters = [
Xcprofiler::StandardOutputReporter.new(limit: 20, order: :time),
Xcprofiler::JSONReporter.new(output_path: 'result.json'),
Xcprofiler::BlockReporter.new do |executions|
do_something(executions)
end,
]
profiler.report!
You can also implement your own reporters.
See implementation of built-in reporters for detail.
You can integrate xcprofiler to danger.
https://github.com/giginet/danger-xcprofiler
MIT License
Bug reports and pull requests are welcome on GitHub at https://github.com/giginet/xcprofiler.