Dynamic dispatch mechanisms
Normally, in a typed language, the dispatch mechanism will be performed based on the type of the arguments (most commonly based on the type of the receiver of a message). This might be dubbed 'per-type dynamic dispatch'. Languages with weak or no typing systems often carry a dispatch table as part of the object data for each object. This allows instance behaviour as each instance may map a given message to a separate method.
动态分发:选择哪个对象来执行。
In computer science, dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time. It is commonly employed in, and considered a prime characteristic of, object-oriented programming (OOP) languages and systems.[1]
Object-oriented systems model a problem as a set of interacting objects that enact operations referred to by name. Polymorphism is the phenomenon wherein somewhat interchangeable objects each expose an operation of the same name but possibly differing in behavior. As an example, a File object and a Database object both have a StoreRecord method that can be used to write a personnel record to storage. Their implementations differ. A program holds a reference to an object which may be either a File object or a Database object. Which it is may have been determined by a run-time setting, and at this stage, the program may not know or care which. When the program calls StoreRecord on the object, something needs to decide which behavior gets enacted. If one thinks of OOP as sending messages to objects, then in this example the program sends a StoreRecord message to an object of unknown type, leaving it to the run-time support system to dispatch the message to the right object. The object enacts whichever behavior it implements.[2]
A language may be implemented with different dynamic dispatch mechanisms. The choices of the dynamic dispatch mechanism offered by a language to a large extent alter the programming paradigms that are available or are most natural to use within a given language.
Normally, in a typed language, the dispatch mechanism will be performed based on the type of the arguments (most commonly based on the type of the receiver of a message). This might be dubbed 'per-type dynamic dispatch'. Languages with weak or no typing systems often carry a dispatch table as part of the object data for each object. This allows instance behaviour as each instance may map a given message to a separate method.
Some languages offer a hybrid approach.
Dynamic dispatch will always incur an overhead so some languages offer static dispatch for particular methods.
C++ implementation[edit]
C++ uses early binding and offers both dynamic and static dispatch. The default form of dispatch is static. To get dynamic dispatch the programmer must declare a method as virtual.
C++ compilers typically implement dynamic dispatch with a data structure called a virtual table (vtable) that defines the message-to-method mapping for a given class (C++ as such has no notion of a vtable). Instances of that type will then store a pointer to this table as part of their instance data. This is complicated when multiple inheritance is used. Since C++ does not support late binding, the virtual table in a C++ object cannot be modified at run-time, which limits the potential set of dispatch targets to a finite set chosen at compile time.
Type overloading does not produce dynamic dispatch in C++ as the language considers the types of the message parameters part of the formal message name. This means that the message name the programmer sees is not the formal name used for binding.
Go and Rust implementation[edit]
In Go and Rust, a more versatile variation of early binding is used. Vtable pointers are carried with object references as 'fat pointers' ('interfaces' in go, or 'trait objects' in Rust).
This decouples the supported interfaces from the underlying data structures. Each compiled library needn't know the full range of interfaces supported in order to correctly use a type, just the specific vtable layout that they require. Code can pass around different interfaces to the same piece of data to different functions. This versatility comes at the expense of extra data with each object reference, which is problematic if many such references are stored persistently.
Smalltalk implementation[edit]
Smalltalk uses a type-based message dispatcher. Each instance has a single type whose definition contains the methods. When an instance receives a message, the dispatcher looks up the corresponding method in the message-to-method map for the type and then invokes the method.
Because a type can have a chain of base types, this look-up can be expensive. A naive implementation of Smalltalk's mechanism would seem to have a significantly higher overhead than that of C++ and this overhead would be incurred for each and every message that an object receives.
Real Smalltalk implementations often use a technique known as inline caching[3] that makes method dispatch very fast. Inline caching basically stores the previous destination method address and object class of the call site (or multiple pairs for multi-way caching). The cached method is initialized with the most common target method (or just the cache miss handler), based on the method selector. When the method call site is reached during execution, it just calls the address in the cache. (In a dynamic code generator, this call is a direct call as the direct address is back patched by cache miss logic.) Prologue code in the called method then compares the cached class with the actual object class, and if they don't match, execution branches to a cache miss handler to find the correct method in the class. A fast implementation may have multiple cache entries and it often only takes a couple of instructions to get execution to the correct method on an initial cache miss. The common case will be a cached class match, and execution will just continue in the method.
Out-of-line caching can also be used in the method invocation logic, using the object class and method selector. In one design, the class and method selector are hashed, and used as an index into a method dispatch cache table.
As Smalltalk is a reflective language, many implementations allow mutating individual objects into objects with dynamically generated method lookup tables. This allows altering object behavior on a per object basis. A whole category of languages known as prototype based languages has grown from this, the most famous of which are Self and JavaScript. Careful design of the method dispatch caching allows even prototype based languages to have high performance method dispatch.
Many other dynamically typed languages, including Python, Ruby, Objective-C and Groovy use similar approaches.
https://en.wikipedia.org/wiki/Dynamic_dispatch
Dynamic dispatch mechanisms的更多相关文章
- Dynamic dispatch
Dynamic dispatch动态调度.动态分发 In computer science, dynamic dispatch is the process of selecting which im ...
- this inspection detects names that should resolved but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Top-level and class-level items are sup
输入第一行代码:import logging;logging.basicConfig(level==logging.INFO) 提示:this inspection detects names tha ...
- 【PyCharm编辑器】之无法导入引用手动新建的包或类,报:This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases.
一.现象描述 如下图所示,手动新建个类包calculator.py,想在test.py文件引用它,发现一直报红线,引用失败 Unresolved reference 'calculator' less ...
- Increasing Performance by Reducing Dynamic Dispatch
https://developer.apple.com/swift/blog/?id=39 Increasing Performance by Reducing Dynamic Dispatch Li ...
- swift -Dynamic Dispatch
These instructions perform dynamic lookup of class and generic methods. The class_method and super_m ...
- Only Link: What's the difference between dynamic dispatch and dynamic binding
http://stackoverflow.com/questions/20187587/what-is-the-difference-between-dynamic-dispatch-and-late ...
- 【Python】This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck
情况一:导包import时发生错误,请参考这两位 https://blog.csdn.net/zhangyu4863/article/details/80212068https://www.cnblo ...
- Which dispatch method would be used in Swift?-Existential Container
In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...
- Which dispatch method would be used in Swift?
In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...
随机推荐
- jquery选择器的一些处理
本文不讨论用jquery选择器具体怎么选择页面元素,而讨论选择元素后后的一些处理 jquery的选择器选择元素的时候,即使没有选择到指定的对象,页面并不会报错,例子: <!doctype htm ...
- Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理
一.spring依赖注入使用方式 @Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byT ...
- sass揭秘之@if,@for,@each(转载)
因为文章内含有很多sass代码,如需自己动手查看编译结果,推荐使用sassmeister这款在线编译工具,方便你阅读学习. 经过上两篇揭秘,大家心里对sass应该有了很好的认知感了,这篇文章基于前面两 ...
- 铁大FaceBook的使用体验
铁大FaceBook是一个类似QQ和微信等聊天程序的缩小版网站,并且其针对领域较为狭窄:即只针对校园的学生和导员等人员.但其有值得推广的潜力性和可能性. 对于使用它的体验:第一点我感觉这个网站的界面很 ...
- 阿里云服务上面部署redis + 本地Redis客户端连接方法
本文结合自己在阿里云服务器上面搭建redis服务器,在本地redis的客户端Redis Desktop Manager连接成功的操作,将操作中的一些方法做了一些归纳和总结,希望可以帮到有需要的同学. ...
- C/C++ 获取文件夹下的所有文件列表
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51009608 提供一段C/C++代码示 ...
- 【jQuery】对于复选框操作的attr与prop
这个是在jQuery1.6版本号之后出现的鬼东西.受影响的主要有下拉列表select与复选框checkbox.众所周知.在jQuery中能够用attr()取出节点的属性,然而对于checkbox却不是 ...
- 通达OA 小飞鱼工作流在线培训教程(一)HTML基础介绍
应一些刚接触工作流设计朋友的要求,这里开设一个系列教程,对通达OA工作流设计相关的内容做个介绍.方便解决一些日常经常出现的问题,希望对刚刚接触这部分工作的朋友能够有些帮助. 工作流设计须要多方面的知识 ...
- RecyclerView的点击事件
RecyclerView 一.简单介绍 这个是谷歌官方出的控件.使我们能够很easy的做出列表装的一个控件,当然recyclerview的功能不止这些,它还能够做出瀑布流的效果,这是一个很强大的控件, ...
- Codeforces 558B Amr and The Large Array
B. Amr and The Large Array time limit per test 1 second memory limit per test 256 megabytes input st ...