Dynamic dispatch
动态调度。动态分发

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]

在计算机科学中,动态调度是“选择一个多态操作(方法或功能)的实现,以在运行时确定调用哪个”的过程。它是通常使用的在面向对象的编程(OOP)语言和系统的一个主要特征。[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]

面向对象的系统把问题建模为“一组相互作用的对象”,互相通过名称沟通。多态性是指对象有公开名称相同的操作,但在行为上可能有所不同。比如,一个文件对象和数据库对象都有一个StoreRecord方法可以用来编写人员记录到存储。他们的实现有所不同。。。。

Dynamic dispatch contrasts with static dispatch, in which the implementation of a polymorphic operation is selected at compile-time. The purpose of dynamic dispatch is to support cases where the appropriate implementation of a polymorphic operation cannot be determined at compile time because it depends on the runtime type of one or more actual parameters to the operation.
与dd相对的是sd静态调度,多态操作的选择是在编译时确定

Dynamic dispatch is different from late binding (also known as dynamic binding). In the context of selecting an operation, binding associates a name to an operation. Dispatching chooses an implementation for the operation after you have decided which operation a name refers to. With dynamic dispatch, the name may be bound to a polymorphic operation at compile time, but the implementation not be chosen until run time. While dynamic dispatch does not imply late binding, late binding does imply dynamic dispatching since the binding is what determines the set of available dispatches.

动态调度和迟绑定(动态绑定)不同。在选择操作方面,绑定把名称和操作联系到一起,而Dispatching为一个操作选择一个实现。对于dd,名称可能在编译时确定,而实现实在运行时确定

Single and multiple dispatch[edit]
单分发和多分发
Main article: Multiple dispatch
The decision of which version of a method to call may be based either on a single object, or on a combination of objects. The former is called single dispatch and is directly supported by common object-oriented languages such as C++, Java, Smalltalk, Objective-C, Swift, JavaScript, and Python. In these and similar languages, one may call a method for division with syntax that resembles
确定哪个方法可能是基于单个对象,或者多个对象的组合。单分发一般oo语言都支持,比如c++,java,smalltalk,oc,...

举例:dividend.divide(divisor)

where the parameters are optional. This is thought of as sending a message named divide with parameter divisor to dividend. An implementation will be chosen based only on dividend's type (perhaps rational, floating point, matrix), disregarding the type or value of divisor.

By contrast, some languages (such as Common Lisp, Dylan, Julia) dispatch methods or functions based on the combination of operands; in the division case, the types of the dividend and divisor together determine which divide operation will be performed. This is known as multiple dispatch.
一些语言分发消息基于操作的组合:这叫做多分发

Dynamic dispatch mechanisms[edit]
动态分发机制
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]
cpp实现
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.
cpp同时支持动态和静态绑定。动态绑定方法需要用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.
cpp编译器通过vtable实现动态分发,vtable定义了指定class的message-to-method mapping。对象会保存vtablke的指针,当存在多继承的时候会很复杂。由于cpp不支持迟绑定,vtable不可以运行时修改,这限制了分发对象的数目在编译期间

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]
go的实现
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).
go使用了早期绑定的一个变体。vtable指针被object 指向,扎叫做'fat pointers' (是说不是每个type一个vtable,而是每个object?)

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.
这解耦了interfacre和底层的data structures.每个lib不需要知道所有支持的interface以便正确的使用该类型

Smalltalk implementation[edit]
Smalltalk的实现
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.
st使用了 type-based的消息分发器。每个实例收到消息后,dispatcher查找对性的方法,再invoke该方法

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.
由于type会有base type链表,这个查找会很慢

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.
真正的实现会使用inline caching加速消息分发。???

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.
由于Smalltalk是反射语言,很多实现对象使用动态生成的method lookup tables。这使得修改objct的香味成为可能。一种基于prototype的语言由此而来。最常见的就是 Self and JavaScript.仔细的设计method dispatch caching可以使prototype based languages都会有好的分发性能

Many other dynamically typed languages, including Python, Ruby, Objective-C and Groovy use similar approaches.
其他动态语言比如python,。。使用类似的技术

Dynamic dispatch的更多相关文章

  1. 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 ...

  2. 【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 ...

  3. Dynamic dispatch mechanisms

    Normally, in a typed language, the dispatch mechanism will be performed based on the type of the arg ...

  4. Increasing Performance by Reducing Dynamic Dispatch

    https://developer.apple.com/swift/blog/?id=39 Increasing Performance by Reducing Dynamic Dispatch Li ...

  5. swift -Dynamic Dispatch

    These instructions perform dynamic lookup of class and generic methods. The class_method and super_m ...

  6. 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 ...

  7. 【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 ...

  8. Double Dispatch讲解与实例-面试题

    引言 说实话,我看过GoF<Design Patterns>,也曾深深的被李建忠<设计模式>系列Webcast吸引.但是还没有见过“Double Dispatch模式”.的确G ...

  9. @OBJC 和 DYNAMIC

    原文转载自:@OBJC 和 DYNAMIC 虽然说 Swift 语言的初衷是希望能摆脱 Objective-C 的沉重的历史包袱和约束,但是不可否认的是经过了二十多年的洗礼,Cocoa 框架早就烙上了 ...

随机推荐

  1. AntPathMatcher做路径匹配

    转发自: http://www.cnblogs.com/leftthen/p/5212221.html 需要看详细的请看上面的链接 这里以我这里的一个Filter 中需要对路径做例外处理,filter ...

  2. tf.trainable_variables() and tf.all_variables()

    tf.trainable_variables()  返回的是 所有需要训练的变量列表 tf.all_variables() 返回的是 所有变量的列表 v = tf.Variable(0, name=' ...

  3. unity3d 九宫密码锁

    using UnityEngine;using System.Collections.Generic;using System;using UnityEngine.EventSystems;using ...

  4. java学习笔记25(Collections类)

    Collections算法类: Collections是一个算法类,提供了一系列静态方法,实现对集合的排序.替换.交换.搜索.拷贝等操作: 用法:Collections.方法名(要操作的集合): 就像 ...

  5. hmtl工具

    在线编辑器:http://runjs.cn/code 关注微信小程序

  6. scrollIntoView()方法

    该方法用于建立一个锚点,点击锚点,会跳到相应的内容,且该内容头部与浏览器头部平齐 实例: <html> <head> <title>TODO supply a ti ...

  7. 4--Python入门--Python数据集合类型--集合

    在基础数据类型的基础上,Python有6中数据集合的类型: 列表list,最常用的数据类型,以[]为标识 元组tuple,和list很相似,但是不能二次赋值,用()标识 集合set,和list类似,但 ...

  8. BUG_sql未解决bug

    [SQL]truncate table org_cert;受影响的行: 0时间: 0.021s [Err] 1055 - Expression #1 of ORDER BY clause is not ...

  9. BZOJ 1083 [SCOI2005]繁忙的都市 (最小生成树裸题无重边) 超简单写法!!

    Description 城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造.城市C的道路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道路相连,两个交叉路口 ...

  10. linux 执行脚本

    crontab -e 直接编辑定时脚本 保存后,在/var/spool/cron/下自动生成一个以用户名命名的脚本文件.