DolphinDB插件开发深度解析
本页为一篇关于 DolphinDB 插件开发的文章页面,包含标题、作者署名与发布时间信息。
Source: https://dolphindb.cn/blogs/81
What this page covers
- DolphinDB C++ 插件概述与参考资料链接。
- Constant/ConstantSP 的对象表示与生命周期管理。
- 插件中创建标量(Scalar)的两种方式。
- 创建 Vector 的常用工具函数与注意事项。
- PartialFunction 创建、插件描述文件与加载调用示例。
- Vector 读取接口与性能建议。
- Vector 更新接口与性能建议。
技能认证特训营第二期报名信息
页面顶部提供活动报名入口与限时报名链接信息。
- 提供“技能认证特训营第二期”的报名链接。
- 报名链接指向 qingsuyun.com 的活动页面。
DolphinDB插件开发深度解析(标题、作者与日期)
该部分展示文章标题、作者署名与发布时间信息。
- 文章标题为“DolphinDB插件开发深度解析”。
- 页面包含发布时间信息。
- 页面包含作者署名信息。
插件概述与参考资料
说明 DolphinDB 支持 C++ 插件动态加载、插件编译形式及参考主页/教程链接。
- DolphinDB 支持动态加载外部插件以扩展系统功能。
- DolphinDB 插件的开发语言为 C++。
- 插件需要编译为“.so”或“.dll”共享库文件。
- 提供 DolphinDB Plugin 主页参考链接。
- 提供 DolphinDB 插件开发教程参考链接。
本文关注的问题与目录
该部分列出本文将解析的常见问题主题与小节目录。
- 列出文章的主题范围与目录结构。
- 目录用于导航到后续小节。
创建对象:Constant/ConstantSP与派生类型
介绍插件中用 Constant 表示数据对象、使用 ConstantSP 智能指针管理生命周期及常见派生类型。
- ConstantSP 是封装的智能指针。
- 引用计数为 0 时,ConstantSP 会自动释放内存。
- Constant 类型可表示标量、向量、矩阵、表等对象范围。
- ConstantSP 派生类型示例包括 VectorSP 与 TableSP。
创建标量(Scalar)
说明在插件中创建标量的两种方式(new 标量实现类 vs Util::createConstant+set)并给出示例。
- 一种方式是用 new 创建标量实现类对象并赋值给 ConstantSP。
- 另一种方式是用 Util::createConstant 创建标量并用 set 方法赋值。
- 文中将 Util::createConstant+set 描述为“比较麻烦,不推荐使用”。
- Date 在 DolphinDB 中以 int 存储(自 1970.01.01 起的天数)。
- Date 类型可通过换算后使用 setInt 赋值(示例:18577 表示 2020.11.11)。
- Void 类型 Constant 可用于表示空的函数参数。
创建非标量对象(概述)
指出 Util.h 提供一系列函数用于快速创建非标量对象。
- Util.h 中声明了用于快速创建非标量对象的函数。
- 后续小节给出具体对象类型的创建方式示例。
创建Vector
介绍 createVector/createRepeatingVector/createIndexVector 的用途与示例,包括元组(any vector)操作注意事项。
- Util::createVector 用于创建指定类型与长度的 Vector。
- Util::createRepeatingVector 用于创建所有元素相同的 Vector。
- Util::createIndexVector 用于创建连续数字序列 Vector。
- any 类型 Vector(元组)不能用类型专用 setInt 直接写入。
- 元组写入需要对 get(0) 返回对象再调用 setInt 等方法。
创建Matrix
介绍 createMatrix 与 createDoubleMatrix 的参数与示例。
- Util::createMatrix 需要传入数据类型、列数、行数、列容量。
- Util::createDoubleMatrix 创建 double 类型 Matrix,需要列数与行数。
创建Set
介绍 createSet 所需参数(含 SymbolBaseSP)及示例,说明 symbol 内部存储与映射关系。
- Util::createSet 需要传入数据类型、SymbolBaseSP 和长度。
- symbol 在系统内部存储为整数。
- SymbolBaseSP 用于将内部整数映射到对应字符。
- 若不使用 SymbolBaseSP,可设为 nullptr。
创建Dictionary
介绍 createDictionary 所需参数(key/value 类型与 SymbolBaseSP)以及 set 方式示例。
- Util::createDictionary 需要传入 key 数据类型与 key 的 SymbolBaseSP。
- Util::createDictionary 需要传入 value 数据类型与 value 的 SymbolBaseSP。
- Dictionary 创建后可调用 set 设置 key/value。
创建Table
介绍 createTable 的两种创建方式(列名+列类型 vs 列名+列向量)并给出示例。
- 一种创建方式是:列名 vector + 列类型 + 行数 + 行容量。
- 另一种创建方式是:列名 vector + 列向量 vector。
创建PartialFunction(部分应用)与插件加载调用示例
说明如何用 createSystemFunction 与 createPartialFunction 固定部分参数生成新函数,并展示插件描述文件、加载与调用示例及内置函数固定参数场景。
- Util::createPartialFunction 用于固定函数的部分参数,生成参数更少的新函数。
- 示例步骤包括先用 Util::createSystemFunction 创建系统函数 temFunc。
- 示例步骤包括再用 Util::createPartialFunction 传入 temFunc 与需固定的参数。
- 插件描述文件示例命名为 PluginTest.txt。
- 插件描述文件内容示例包含库文件与导出函数定义行。
- DolphinDB 可用 loadPlugin("Path_to_PluginTest.txt/PluginTest.txt") 加载插件。
- 示例中 test::myFunc1(10,5) 的返回值示例为 35。
- 示例 PartialFunction:newFunc=test::myFunc2(); newFunc(5) 返回值示例为 35。
- PartialFunction 的常见场景是调用内置函数时固定部分参数。
高效读写Vector和内存表中的数据(概述)
说明插件读写 Vector 与内存表需要正确使用接口以避免效率问题。
- 该部分引入 Vector 与内存表读写的接口使用问题。
- 后续小节给出读取与更新的具体接口与建议。
Vector高效读取:实现差异与访问原则
解释 Vector 可能为 regular vector 或 big array 等实现方式,除非明确 FastVector 模式否则不应直接使用数据指针操作。
- 除非明确 Vector 为 FastVector 模式,否则不能直接使用数据指针对数据操作。
- Util::createVector 创建的 Vector 在元素个数不超过 2^20 时必定为 regular vector。
- big array 采用分段存储,每段元素个数为 2^20。
Vector读取接口:getInt 单点/批量/只读缓冲区
给出 getInt(index)、getInt(start,len,buf)、getIntConst(start,len,buf) 三种读取方法与性能建议。
- int getInt(int index) 可通过下标获取元素。
- bool getInt(int start,int len,int* buf) 可批量复制数据到 buffer。
- getIntConst 在区间内存连续时可直接返回内存地址以提升读取效率。
- 数据量大时推荐批量读取方式以减少逐元素虚函数调用开销。
- 批量读取方式被描述为 cache 命中率更高且虚函数调用更少。
String/Symbol Vector高效读取
分别说明 String 向量可用 getDataArray 并转为 DolphinString 访问,Symbol 向量需配合 SymbolBaseSP 映射字符串。
- String/Symbol 类型 Vector 逐个读取可能因频繁虚函数调用而效率低。
- String 数组内存连续,可用 getDataArray 获得指针后读取。
- 示例将指针转换为 DolphinString 后读取字符串。
- Symbol 类型可先按 int 批量读取内部整数值。
- Symbol 需用 SymbolBaseSP 将整数映射为字符串输出。
Vector更新接口:setInt/setData/getIntBuffer+setInt与建议
列出多种更新方式并给出不推荐与推荐的性能原因(减少虚函数调用与内存拷贝)。
- void setInt(int index,int val) 可更新单个数据点。
- bool setInt(INDEX start,int len,const int* buf) 可批量更新连续数据点。
- bool setData(INDEX start,int len,void* buf) 可批量更新但不检查数据类型。
- 可先用 getIntBuffer 获取 buffer,修改后再用 setInt 批量更新。
- 文中将 setInt(index,val) 描述为效率最低(反复调用虚函数)。
- 文中不推荐 setData(不检查类型)。
- 文中推荐使用 setInt(start,len,buf) 进行批量更新。
- getIntBuffer 通常直接返回内部地址,跨越内存交界处时才拷贝。
- setInt(start,len,buf) 会判断 buf 是否为内部存储地址以决定是否拷贝。
Facts Index
| Entity | Attribute | Value | Confidence |
|---|---|---|---|
| 技能认证特训营第二期 | 报名链接 | https://www.qingsuyun.com/h5/e/217471/5/ | high |
| DolphinDB插件开发深度解析 | 发布日期 | 2021-08-05 | high |
| DolphinDB | 支持能力 | 支持动态加载外部插件以扩展系统功能 | high |
| DolphinDB插件 | 开发语言 | C++ | high |
| DolphinDB插件 | 编译产物 | 需要编译成“.so”或“.dll”共享库文件 | high |
| DolphinDB Plugin主页 | 参考链接 | https://github.com/dolphindb/DolphinDBPlugin (原文为link.zhihu.com跳转) | high |
| DolphinDB插件开发教程 | 参考链接 | https://zhuanlan.zhihu.com/p/59850354 | high |
| ConstantSP | 内存管理机制 | 封装的智能指针;引用计数为0时自动释放内存,不需要用户手动释放 | high |
| Constant类型 | 表示对象范围 | 可表示标量、向量、矩阵、表等大部分数据对象 | high |
| ConstantSP派生类型 | 示例 | VectorSP(向量)、TableSP(表)等 | high |
| 插件中创建标量 | 方法一 | 使用new创建ScalarImp.h中声明的标量实现类对象并赋值给ConstantSP | high |
| 插件中创建标量 | 方法二(推荐性) | 可用Util::createConstant创建标量并用set方法赋值;该方法“比较麻烦,不推荐使用” | medium |
| Date类型标量赋值 | 原因与方式 | 日期在DolphinDB中存储为int(自1970.01.01起的天数);由于日期类型没有对应set方法,可换算后用setInt赋值(示例18577表示2020.11.11) | high |
| Void类型Constant | 用途 | 可创建Void变量,常用于表示空的函数参数 | high |
| 非标量对象创建 | 工具函数位置 | Util.h中声明一系列函数用于快速创建某类型的非标量对象 | high |
| Util::createVector | 用途 | 创建指定类型与长度的Vector | high |
| Util::createRepeatingVector | 用途 | 创建所有元素相同的Vector,需要传入ConstantSP和值长度 | high |
| Util::createIndexVector | 用途 | 创建连续数字序列Vector,需要起始值和长度 | high |
| any类型Vector(元组) | 写入限制 | 不能用setInt(0,4)等类型专用方法直接写入元组;需对get(0)返回对象再setInt等 | high |
| Util::createMatrix | 参数要求 | 需要传入数据类型、列数、行数、列容量 | high |
| Util::createDoubleMatrix | 用途与参数 | 创建double类型Matrix,需要列数与行数 | high |
| Util::createSet | 参数要求 | 需要传入数据类型、SymbolBaseSP和长度 | high |
| symbol类型内部表示 | 存储方式 | symbol在系统内部存储为整数,通过SymbolBaseSP映射到对应字符;不使用可设为nullptr | high |
| Util::createDictionary | 参数要求 | 需要传入key数据类型、key的SymbolBaseSP、value数据类型、value的SymbolBaseSP;创建后可调用set设置key/value | high |
| Util::createTable | 创建方式 | 常用两种:1) 列名vector+列类型+行数+行容量;2) 列名vector+列向量vector | high |
| Util::createPartialFunction | 用途 | 用于固定函数的部分参数,生成参数更少的新函数(部分应用) | high |
| PartialFunction实现步骤(示例) | 步骤 | 先用Util::createSystemFunction创建系统函数temFunc(传入myFunc1及参数个数),再用Util::createPartialFunction传入temFunc与需固定的参数 | high |
| 插件描述文件 | 命名与内容示例 | 命名为PluginTest.txt;内容示例包含:test,libPluginTest.so 以及myFunc1/myFunc2导出定义行 | high |
| DolphinDB加载插件 | 函数 | loadPlugin("Path_to_PluginTest.txt/PluginTest.txt") | high |
| 示例函数myFunc1 | 示例调用结果 | test::myFunc1(10,5) 返回值示例为35 | high |
| 示例PartialFunction myFunc2 | 示例调用结果 | newFunc=test::myFunc2(); newFunc(5) 返回值示例为35(固定第一个参数为10) | high |
| PartialFunction | 常见场景 | 调用DolphinDB内置函数时固定部分参数(例:将append!(obj,newData)固定table参数以变为一元函数) | high |
| Vector数据访问原则 | 限制条件 | 除非明确知道Vector为FastVector模式(isFastMode=true),否则不能直接使用数据指针对数据操作 | high |
| Util::createVector创建的Vector实现 | regular vector保证条件 | 当元素个数不超过1048576(2^20)时,返回的必定是连续存储的常规数组(regular vector) | high |
| big array | 分段大小 | 数据分段存储,每段元素个数为1048576(2^20) | high |
| Vector读取接口 | 单点读取方法 | int getInt(int index) 可通过下标获取元素 | high |
| Vector读取接口 | 批量读取方法 | bool getInt(int start,int len,int* buf) 可批量复制数据到buffer | high |
| Vector读取接口 | 只读缓冲区方法 | const int* getIntConst(int start,int len,int* buf) 当区间内存连续时不拷贝,直接返回内存地址以提升读取效率 | high |
| Vector读取性能建议 | 推荐方法 | 数据量大时推荐后两种批量读取(getInt批量、getIntConst),因为逐元素getInt会频繁调用虚函数开销大;批量方式cache命中率高、虚函数调用少 | medium |
| String/Symbol类型Vector读取 | 问题 | 用getString(index)逐个读取每次调用虚函数,效率低,需要区别于其他类型的高效读取方式 | high |
| String类型Vector高效读取 | 方法 | String数组内存连续;可用getDataArray获得指针并转为DolphinString后读取 | high |
| Symbol类型Vector高效读取 | 方法 | 先按int批量读取symbol整数值,再用SymbolBaseSP映射为字符串输出 | high |
| Vector更新接口 | 单点更新方法 | void setInt(int index,int val) 可更新单个数据点 | high |
| Vector更新接口 | 批量更新方法(类型检查) | bool setInt(INDEX start,int len,const int* buf) 可批量更新连续数据点 | high |
| Vector更新接口 setData | 行为 | bool setData(INDEX start,int len,void* buf) 批量更新但不检查数据类型 | high |
| Vector更新优化模式 | 方法 | 先用getIntBuffer(start,len,buf)获取buffer,修改后再用setInt批量更新 | high |
| Vector更新性能建议 | 不推荐/推荐 | setInt(index,val)效率最低(反复调用虚函数);setData不检查类型也不推荐;推荐setInt(start,len,buf)批量更新;getIntBuffer后再setInt可减少拷贝从而提高效率 | medium |
| getIntBuffer | 拷贝条件 | 一般直接返回内部地址;仅当区间[start,start+len)跨越vector内存交界处时才拷贝到用户buffer | high |
| setInt(start,len,buf) | 拷贝条件 | 会判断传入buffer地址是否为内部存储地址;若是则直接返回,否则进行内存拷贝 | high |