Swift Log - Devil
Why print is dangerous
First let’s have a look at one of my favourite Swift features, code optimisation.
Swift compiler is very smart. The code the compiler emits will omit unnecessary operations, for example:
- Unused variables
- Empty loops
- Empty function calls
For example lets have a look on this code and compile it with Optimization enabled and without
Here are results: Left -Ounchecked, Right -Onone
The difference is huge!! This code is completely removed when optimisation is enabled. After Swift compiler performs all the optimisations steps, the testFunc becomes empty, so it gets removed.
You can read more about Swift Speed optimisation at Secrets of Swift’s Speed by Mike Ash
We use logging for debugging purpose. In Swift we would use print and debugPrint statements for that. Because we are using logging for a debugging it should be removed from the productions code. Let’s add a log statement to our previous code example and see what’s happen.
We have added just 1 line of code print(y)
The result is very astonishing! The Swift compiler doesn’t remove print and debugPrint statements at the compile time, even when -Ounchecked optimisation is enabled. Because of that let y variable gets used in print statement, and for i in 0…100 loop is not empty anymore and testFuc as well and Swift compiler can’t remove anything. All of that leads to a big performance decrease.
This all happens because of One Small print statement.
Removing the Log
There is a solution for it. We could simply use a preprocessor condition to remove print statement when it’s not needed.
This solution would work but the code doesn’t look so nice anymore and we need to put #if DEBUG #endif everywhere. The obvious solution for solving that would be moving these preprocessor statements into a separate function or a type, like structure, and reuse them.
This is exactly what I did. I’ve made a simple logging library SpeedLog.
The SpeedLog gives you ability to very easy to disable logs and remove them before compiling swift code. It also has some nice formatting features that allows you to show file and function name and a line number for that log statement.
Keep your logs clean and don’t let it decrease your application performance.
If you like having powerful logging framework like CocoaLumberjack or XCGLogger I’m planning to keep working on the SpeedLog and would love if you contribute to it
Swift High Performance
If you enjoyed this article check out Swift High Performance book