首页/新闻资讯/正文详情

Apache Arrow Red Gandiva 实战:用 Ruby 对 Arrow 数据编译与求值表达式的 GObject 绑定指南

发布时间:2026/9/23 23:24:50 来源:云帆数科 栏目:资讯中心
Apache Arrow Red Gandiva 实战:用 Ruby 对 Arrow 数据编译与求值表达式的 GObject 绑定指南
数据工程大数据序列化数据分析【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址https://gitcode.com/gh_mirrors/arrow13/arrow点击查看免费下载Red Gandiva 是 Apache Arrow 生态中 Gandiva 表达式引擎的 Ruby 绑定它基于 GObject Introspection 在运行时自动生成绑定让你可以直接用 Ruby 的语法、、if等构造表达式再交给 Gandiva 编译并对 RecordBatch 进行向量化求值。本文以仓库中的 ruby/red-gandiva/README.md 为主体结合源码、测试与 GLib 层实现完整讲解其架构、安装方式、表达式构建 DSL 与求值流程读完即可在 Ruby 项目中落地 Gandiva 表达式投影。什么是 Red Gandiva一层一层的绑定体系Red Gandiva 是 Gandiva 的 Ruby 绑定Ruby bindings of Gandiva。Gandiva 是一套用于在 Arrow 数据上编译并求值表达式的工具集a toolset for compiling and evaluating expressions on Arrow data它把开发者用 DSL 写出的表达式编译成高效的机器码再以向量化的方式作用到整批 Arrow 列数据上。Red Gandiva 的独特之处在于它并不手工编写一层层 C 接口代码而是依赖两层中间件自动生成GObject IntrospectionC 语言库的跨语言绑定中间件middleware for language bindings of C library能够在运行时自动生成语言绑定省去手写大量胶水代码。gobject-introspection gemGObject Introspection 的 Ruby 绑定Red Gandiva 正是经由这个 gem 使用 GObject Introspection。但 GObject Introspection 无法直接消费 Gandiva 的 C 接口因此在中间还隔着一层 C 包装Gandiva GLib仓库中位于 c_glib/gandiva-glib是 Gandiva C 的 C 包装器扮演Gandiva C 与 GObject Introspection 之间的桥梁Red Gandiva 组合使用 Gandiva GLib 与 gobject-introspection gem 来生成 Gandiva 的 Ruby 绑定。整体依赖链可以表示为Ruby 代码Red Gandiva DSL │ ▼ gobject-introspection gem运行时自动生成绑定 │ ▼ Gandiva GLibC 包装层位于 c_glib/gandiva-glib │ ▼ Gandiva C编译与向量化求值内核位于 cpp/src 下 gandiva 相关实现入口与加载机制从 require 到自动绑定Red Gandiva 的入口是 ruby/red-gandiva/lib/gandiva.rb它依次做了三件事require arrow # 先加载 Red Arrow require gandiva/version require gandiva/loader # 再加载绑定生成器随后由 ruby/red-gandiva/lib/gandiva/loader.rb 中的Gandiva::Loader完成绑定注入class Loader GObjectIntrospection::Loader def self.load super(Gandiva, Gandiva) end endLoader.load让 GObject Introspection 扫描名为Gandiva的 GIR 命名空间由 Gandiva GLib 提供并把其中的类、方法、枚举自动映射成 Ruby 类与方法。加载完成后post_load还会引入两个扩展库ruby/red-gandiva/lib/gandiva/arrow-schema.rb给Arrow::Schema追加build_expression方法ruby/red-gandiva/lib/gandiva/expression-builder.rb表达式 DSL 的核心实现。此外Loader 还做了一处方法名适配把 Gandiva GLib 的BooleanLiteralNode#value?映射为 Ruby 风格更自然的#value见 loader.rb。安装先装 Gandiva GLib再装 Red GandivaRed Gandiva 是纯 Ruby 绑定层真正的计算内核在 C 侧。因此安装有明确的前置顺序先安装 Gandiva GLib及其背后的 Gandiva C / Arrow C。README 明确要求在安装 Red Gandiva 之前先安装 Gandiva GLib具体可参考 Apache Arrow 官方安装文档提供的各发行版安装方式。再安装 Red Gandiva gem% gem install red-gandivagem 自身的依赖约束可以看 ruby/red-gandiva/red-gandiva.gemspec运行时强依赖red-arrow且版本与 Red Gandiva 自身完全一致spec.add_runtime_dependency(red-arrow, #{spec.version})开发期依赖bundler、rake、test-unitspec.extensions [dependency-check/Rakefile]表示安装 gem 时会执行依赖检查。依赖检查逻辑位于 ruby/red-gandiva/dependency-check/Rakefile在 Linux/macOS 上通过PKGConfig.check_version?(gandiva-glib, MAJOR, MINOR, MICRO)校验本机 Gandiva GLib 的版本是否满足要求若缺失或版本不匹配则调用NativePackageInstaller尝试自动安装系统包Debian 系对应libgandiva-glib-devRedHat 系对应gandiva-glib-devel在 Windowsmingw|mswin平台则跳过该检查。仓库内的 ruby/red-gandiva/Gemfile 还展示了从源码仓库直接联调的方式通过gem red-arrow, path: ../red-arrow指向同仓库的 Red Arrow 目录进行开发测试。快速上手构造 Table、构建表达式并求值README 提供了一个完整、可直接运行的示例核心流程是建表 → 取 schema → 用 DSL 构建表达式 → 创建 Projector → 逐 RecordBatch 求值require gandiva table Arrow::Table.new(:field1 Arrow::Int32Array.new([1, 2, 3, 4]), :field2 Arrow::Int32Array.new([11, 13, 15, 17])) schema table.schema expression1 schema.build_expression do |record| record.field1 record.field2 end expression2 schema.build_expression do |record, context| context.if(record.field1 record.field2) .then(record.field1 / record.field2) .else(record.field1) end projector Gandiva::Projector.new(schema, [expression1, expression2]) table.each_record_batch do |record_batch| outputs projector.evaluate(record_batch) puts outputs.collect(:values) end几点使用要点require gandiva会连带加载 Red Arrowrequire arrow因此可以直接使用Arrow::Table、Arrow::Int32Arrayschema.build_expression返回的是Gandiva::Expression对象可以一次性构造多个表达式组成数组传给Gandiva::Projectorprojector.evaluate(record_batch)返回多个输出数组Array与传入的表达式一一对应table.each_record_batch保证了在大表场景下按 RecordBatch 分批求值条件表达式使用context.if(...).then(...).else(...)链式写法条件里的record.field1 record.field2返回的是表达式节点而不是 Ruby 布尔值因此不会在 Ruby 侧发生短路求值。表达式构建器 DSL源码级的运作原理1.Arrow::Schema#build_expression与Gandiva::ExpressionBuilderbuild_expression是在 Red Gandiva 加载时被注入到Arrow::Schema上的扩展方法见 arrow-schema.rbmodule Arrow class Schema def build_expression(block) builder Gandiva::ExpressionBuilder.new(self) builder.build(block) end end endExpressionBuilder#build见 expression-builder.rb是 DSL 的收口点它把用户 block 中record与context两个对象交给 block拿到 block 返回值后调用build得到一棵节点树最终包成带输出字段的表达式def build builder yield(Record.new(schema), Context.new) node builder.build Expression.new(node, Arrow::Field.new(result, node.return_type)) end也就是说每个表达式最终都会生成一个名为result、类型由节点树推导出的输出字段。2.Record用方法名访问 schema 字段block 的第一个参数是 record.rb 中的Record对象。它通过method_missingrespond_to_missing?实现字段名即方法名def method_missing(name, *args) return super unless args.empty? self[name] || super end def [](name) field schema[name] field ? Field.new(field) : nil end因此record.field1会被解析为 schema 中名为field1的字段包装成Field值对象若字段不存在则回退到super例如抛出正常的 NoMethodError。3.Value运算符重载构造表达式树Field、Literal、二元运算等共同继承自 value.rb 中的Value它重载了 Ruby 运算符来构造 ASTdef (right) Add.new(self, resolve(right)) end def -(right) Subtract.new(self, resolve(right)) end def *(right) Multiply.new(self, resolve(right)) end def /(right) Divide.new(self, resolve(right)) end def (right) GreaterThan.new(self, resolve(right)) end def (right) LessThan.new(self, resolve(right)) end def (right) Equal.new(self, resolve(right)) end其中resolve(value)会先把 Ruby 字面量转成Literal节点Literal.resolve(value) or value所以record.field1 1、record.field2 * 3这类字段混合字面量的写法是合法的。每个二元运算如 add.rb都继承自 binary-operation.rb最终生成一个FunctionNodeFunctionNode.new(operator, [left_node, right_node], return_type(left_node, right_node))以Add为例其return_type会取左右操作数中位宽更大的一侧作为结果类型源码中留有注释说明目前实现较朴素例如(int64, float) - float这类跨类型提升尚未支持。4.LiteralRuby 字面量到 Gandiva 节点的类型映射ruby/red-gandiva/lib/gandiva/expression-builder/literal.rb 中的Literal.resolve按 Ruby 值类型自动挑选最窄的 Gandiva 字面量节点Ruby 字面量Gandiva 节点true/falseBooleanLiteralNode小于-(2**31)的整数Int64LiteralNode小于-(2**15)的整数Int32LiteralNode小于-(2**7)的整数Int16LiteralNode小于0的整数Int8LiteralNode小于2**8-1的整数UInt8LiteralNode小于2**16-1的整数UInt16LiteralNode小于2**32-1的整数UInt32LiteralNode其余整数UInt64LiteralNodeFloatDoubleLiteralNodeStringStringLiteralNode这套按值域自动缩窄的策略能尽量使用更小的类型承载常量从而在生成表达式树阶段就获得更紧凑的类型信息。5.Context#if条件表达式链block 的第二个参数是 context.rb 中的Context目前只提供ifclass Context def if(condition) If.new(condition) end endif.rb 中的If支持then、else、elsif链式调用build时生成IfNode.new(condition_node, then_node, else_node, return_type)当then与else都存在时结果类型取then分支的返回类型源码注释标明此处尚未做then/else分支类型一致的强校验属于待完善点elsif通过 elsif.rb 实现本质是把父级If的条件、then分支与新的elsif节点重新组合成一颗IfNode从而支持if ... elsif ... else多分支。Projector 求值从 Ruby 到 Gandiva C 的调用链Gandiva::Projector是求值入口Gandiva::Projector.new(schema, [expression1, expression2])接收 schema 与表达式数组。调用projector.evaluate(record_batch)后Ruby 侧通过 GObject Introspection 生成的绑定调用 Gandiva GLib 的 C 接口Gandiva GLib 侧c_glib/gandiva-glib/projector.cpp把GList *expressions转为 C 表达式并构造std::shared_ptrgandiva::Projector——见 c_glib/gandiva-glib/projector.hpp 中ggandiva_projector_new_raw的声明Gandiva C 内核完成表达式编译与按 RecordBatch 的向量化求值结果回传给 Ruby 侧输出数组。仓库测试 ruby/red-gandiva/test/test-projector.rb 给出了一个覆盖四则运算与elsif多分支的完整验证用例可作为实战参考table Arrow::Table.new(:field1 Arrow::Int32Array.new([1, 13, 3, 17]), :field2 Arrow::Int32Array.new([11, 2, 15, 17]), :field3 Arrow::Int32Array.new([1, 10, 2, 2])) schema table.schema expression1 schema.build_expression do |record| record.field1 record.field2 end expression2 schema.build_expression do |record, context| context.if(record.field1 record.field2) .then(record.field1 record.field2 * record.field3) .elsif(record.field1 record.field2) .then(record.field1 - record.field2 / record.field3) .else(record.field2) end projector Gandiva::Projector.new(schema, [expression1, expression2]) table.each_record_batch do |record_batch| outputs projector.evaluate(record_batch) assert_equal([[12, 15, 18, 34], [11, 33, 15, 9]], outputs.collect(:values)) end该用例同时印证了几点 DSL 语义record.field1 record.field2生成的是相等判断节点而非 Ruby 比较expression2中三个分支的返回类型一致Int32因此IfNode能正常构造多个表达式在同一个 Projector 中并行求值输出顺序与表达式传入顺序一致。与之配套的表达式构建器测试位于 ruby/red-gandiva/test/expression-builder/可在此基础上扩展更多运算符与字面量的边界用例。适用边界与延伸聚焦表达式投影Red Gandiva 的核心能力是在 Arrow 数据上编译并求值表达式README 对 Gandiva 的原始定义主要面向表达式投影场景。若需要条件过滤Gandiva GLib 层还提供Filter、SelectableProjector、FunctionRegistry等能力见 c_glib/gandiva-glib 下的 filter、function-registry、native-function 等文件可结合 Gandiva GLib 的 C 接口进一步封装使用。版本强绑定由于绑定是运行时基于 Gandiva GLib 的 GIR 生成的Red Gandiva 与本地 Gandiva GLib 的版本必须匹配依赖检查 Rakefile 中做了严格校验升级任一环节时需保持同步。部署前提目标机器必须已安装 Gandiva GLib 及其背后的 Arrow C / Gandiva C 运行库Red Gandiva 本身不捆绑原生二进制。赞分享数据工程大数据序列化数据分析【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址https://gitcode.com/gh_mirrors/arrow13/arrow点击查看免费下载相关推荐douyin-downloader 实操指南抖音无水印批量下载 10 分钟跑通douyin downloader 实操指南抖音无水印批量下载 10 分钟跑通 douyin downloader 是一个开源抖音无水印批量下载工具一份配置网页爬虫CLIRed Gandiva在 Ruby 中借助 Gandiva 编译与求值 Arrow 表达式Red Gandiva在 Ruby 中借助 Gandiva 编译与求值 Arrow 表达式 Red Gandiva 是 Apache Arrow 项目中 Ga数据工程数据分析大数据Red Arrow基于 GObject Introspection 的 Apache Arrow Ruby 绑定入门与实战Red Arrow基于 GObject Introspection 的 Apache Arrow Ruby 绑定入门与实战 Red Arrow 是 Apach数据工程数据分析大数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

药物协同作用预测实战:基于PyTorch的Transformer预训练模型微调指南
药物协同作用预测实战:基于PyTorch的Transformer预训练模型微调指南

简介:基于PythonJupyter Notebook与Transformer预训练模型的抗癌药物协同作用预测项目包,覆盖数据预处理、模型构建与评估的完整流程,适用于高校毕业设计、课程设计或药物研发领域初学者进阶。资源共481个文件,其中450个CSV数据文… · 2026/9/23 23:24:44

《辐射4》次世代控制台召唤原理与稳定实践指南
《辐射4》次世代控制台召唤原理与稳定实践指南

1. 次世代更新带来的控制台生态剧变:从“能用”到“慎用”的分水岭《辐射4》次世代更新(Next Generation Update)不是一次简单的画质升级,它是一次底层架构的重写。我第一时间在PS5和Xbox Series X上反复测试过——原版PC端那些随… · 2026/9/23 23:24:44

YOLOv8智能小车实战:从数据集到边缘部署的完整指南
YOLOv8智能小车实战:从数据集到边缘部署的完整指南

简介:这套资源面向需要快速上手目标检测与小车识别场景的开发者,提供已训练好的YOLOv8智能小车检测权重、完整数据集以及训练评估图表。检测模型可直接加载使用,数据集图片为jpg,并同时提供xml与txt两种标注格式,分别存… · 2026/9/23 23:24:43

PSO优化RBF神经网络:轻量级协同调参实战指南
PSO优化RBF神经网络:轻量级协同调参实战指南

简介:本资源是一个基于粒子群优化(PSO)算法实现RBF神经网络参数调优的轻量级Python实践项目,面向机器学习初学者与算法优化实践者,聚焦于非线性拟合与分类任务中RBF网络结构参数(如中心、宽度、权值&#x… · 2026/9/24 0:40:41

基于MediaPipe和OpenCV的手势识别与手指计数实战
基于MediaPipe和OpenCV的手势识别与手指计数实战

简介:基于Python语言,结合OpenCV与MediaPipe的手势识别及手指计数项目,面向需要完成计算机毕设或入门计算机视觉的开发者,提供可直接运行的完整代码与测试数据。资源包共5个文件,包含2个Python脚本、2个Markdown说明文… · 2026/9/24 0:40:34

深入解析 SpaceX-API v4 payloads 端点:载荷数据获取、字段模型与查询实践
深入解析 SpaceX-API v4 payloads 端点:载荷数据获取、字段模型与查询实践

后端API设计 【免费下载链接】SpaceX-API :rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data. 项目地址: https://gitcode.com/gh_mirrors/spa/SpaceX-API 点击查看 免费下载 导读 /v4/payloa… · 2026/9/24 0:40:16

攻克 mal 实现难点:Hints 指南中的时间戳、函数引用、I/O 与 Reader 设计
攻克 mal 实现难点:Hints 指南中的时间戳、函数引用、I/O 与 Reader 设计

示例工程 【免费下载链接】mal mal - Make a Lisp 项目地址: https://gitcode.com/gh_mirrors/ma/mal 点击查看 免费下载 mal(Make a Lisp)是一个用数十种语言逐步实现 Lisp 解释器的教学项目。在编写 step0 到 stepA 的过程中,实… · 2026/9/24 0:40:16

大数据入门学习顺序:Hadoop、Hive、Spark、Flink等九大组件最小链路搭建指南
大数据入门学习顺序:Hadoop、Hive、Spark、Flink等九大组件最小链路搭建指南

简介:这是一份面向大数据初学者与转行开发者的系统入门资料包,围绕Hadoop、Hive、Spark、Storm、Flink、HBase、Kafka、Zookeeper、Flume等主流组件展开,覆盖学习路线、技术栈思维导图、常用软件安装指南,以及环境搭建、命令实操、… · 2026/9/24 0:40:04

CodeBurn 中 OpenCode 用量追踪:数据目录解析、双代存储格式与计费路由实战指南
CodeBurn 中 OpenCode 用量追踪:数据目录解析、双代存储格式与计费路由实战指南

【免费下载链接】codeburn Free, local tool to track AI coding token usage and cost across 37 tools and agents (Claude Code, Cursor, Codex, Gemini and more), by model, project, and task. npx codeburn 项目地址: https://gitcode.com/gh_mirrors/co/cod… · 2026/9/24 0:40:04

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码