Swift Method Dispatching — a summary of my talk at Swift Wa
Swift Method DispatchingWhen announcing?Swift,Apple described it as being much faster than Objective-C. On the web,there is a number of?comparsions?juxtaposing speed of both languages. In my opinion,the way Swift dispatches method invocations has the biggest impact on its performance. Leaving the assessment of method dispatch performance aside,let’s focus on understanding how it works in Swift. Before looking into the Swift method dispatching,it is worth making a short recollection of the Objective-C method dispatching. Objective-C Method DispatchingDuring the compilation process,Clang translates each method invocation into a call to the? For example,the? Basically,the?
?
First,it obtains a class of the passed?
?
Then,it tries to look for a method implementation in a class cache.
?
Finding a selector in the cache is a relatively fast operation — as fast as a look-up in the hashmap. However,in the case of cache miss,the program has to take a slower path and call?
?
This method is relatively slow. Finally,?
?
Before looking at the Swift method dispatching,let’s get familiar with two important notions. Name ManglingSwift allows a programmer to define many entities with the same name,e.g. the same class names in different modules or the same method names in different classes. Moreover,Swift allows method overloading. Linker resolves external references by symbols names,when combining object files. That is why,the compiler needs to produce unique symbol names and does it by encoding every entity name. This process of name encoding is called?name mangling. Let’s take a look at an example of Swift method signatures and corresponding mangled symbol names:
?
They are defined in the same class and have the same name,so we deal with a simple example of method overloading. It is worth noting,that Swift method takes an object instance as a first argument to use it as a? Now,take a look at symbol names being a result of mangling the above signatures:
?
The first method takes a string type parameter marked as? Obviously,the above should not give any reason for concern in the everyday development work. But when there is a need,a symbol can be easily demangled using this handy command passing the symbol as a parameter:
?
If you would like to read more about method mangling,there is no better article than the one on the?NSBlog. Before diving into the Swift method dispatching,let’s take a look at one more thing. Namely,let’s see how Swift compiler translates a code into a binary executable. CompilationSwift compilation consists of several phases. At first,a Swift Front End translates a Swift code into a high-level,platform agnostic?SIL?(Swift Intermediate Language). Everyone can examine?SIL?using the? Again,all you need to be aware of is that there are a couple of phases and that you can use an early phase output to analyse a program code. If you wish to read more about Swift compilation,please refer to?John Siracusa’s article. Now,let’s get to the the point… Virtual Method TableVirtual Method Table?is a mechanism used in Swift and many other languages to support run time method binding. We are going to investigate what it looks like in Swift. Let’s take the following two classes:
?
They present an? Now,let’s take a look at the following snippet from the generated?SIL?code:
?
A bit more transparent view may be of help:
?
The above shows that the?SIL?virtual method table is basically a dictionary that maps method names to their implementations (function pointers). In the? The? Let’s get into details by skipping?IR?and looking directly into the Assembly. Here is a code snippet from the output of the?
?
The above snippet shows some similarity to?SIL?vtables. The first line presents?
?
The above method is used by the Matrix to make a simple test of the?
?
I must warn you that I have cleaned the above listing a little bit. I have removed code lines which run in constant time and are not significant for this investigation (that is ARC code and local variables code). But this is still impressive — Swift code maps almost directly to processor instructions! So what is there left? The first line contains just a global function symbol declaration. Look at the second line.?rdi?is a register in the Intel x86-64 architecture that usually holds a value of a function’s first argument. In our case,a value of the first argument is a pointer to the? In the test function assembly,there are also three function calls to some computed addresses and one function call to a well-known address. Remember that the? To clarify the code above,let’s look at it in the form of a pseudo-code:
?
It does not compile,but it makes the situation more clear. In the second line,an argument pointer is being dereferenced and casted to a metadata pointer (metadata will serve as vtable). Then,it adds an offset of 0x58 to the metadata pointer and dereferences it. Wait a minute… let’s look back at the?direct type metadata?in the assembly! (I have just added some exemplary file offsets in the left column):
?
It may appear strange and probably be an implementation detail,but an object’s metaclass pointer points to the third element of its?direct type metadata. Don’t be concerned about it — this is irrelevant in this investigation. Important is that the?
Look at the?
?
The? Let’s take a look at the metadata again. It becomes obvious that the vtable dictionary-like structure has not been lost. It has just morphed into a form in which a mapping key is defined as an offset in the metadata. Something like that:
?
OptimizationsAll the?SIL?and?assembly?code listings in this article were produced without the optimization?
so the final code can be even faster :) SummaryLet’s wrap up! That was a long journey through the depths of Swift. You saw that Swift uses vtables for method dispatching. Because of that,method dispatching in Swift is much simpler and faster — so more battery saving. Unfortunately,in the case of a regular app,the speed gain will probably be insignificant,unless the app does some complex computations. By its very definition,vtable dispatch has one big disadvantage — it lacks dynamism so commonly used by Objective-C programmers and in Cocoa frameworks. If you decide to code in Swift,you will probably end up mixing in some Objective-C. ? https://allegro.tech/2014/12/swift-method-dispatching.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- makefile – 进行递归干运行
- c# – Environment.SetEnvironmentVariable需要很长时间才能
- c# – 显示GridView的页脚总数,并在最后一列中添加列(行虎钳
- 为什么我的Ajax调用中的“等待”长度如此之长? (Chrome网络
- ruby-on-rails – Rails:如何在表单’submit’上指向结果页
- c# – Xamarin中的WebException,使用HttpClient
- React Native环境搭建
- 如何在Playground中运行异步回调
- swift – 在init与之后的隐式解包可选
- c# – MarshalAs(UnmanagedType.LPWStr)和Marshal.PtrToStr