Lua与嵌入式Lisp以及其他可能的候选方案相比较,用于集合数据处理。
当前选择:lua-jit。令人印象深刻的基准测试,我已经习惯了语法。编写高性能ABI将需要谨慎考虑如何构建我的C++。
其他感兴趣的问题
- Gambit-C和Guile作为可嵌入的语言
- Lua性能技巧(有禁用收集器的选项,并且始终可以在处理运行结束时调用收集器)。
背景
我正在开发一个实时高容量(复杂)事件处理系统。我有一个DSL,表示事件结构的模式,存储格式,某些特定于域的结构,发射内部事件(以结构和驱动通用处理为例),以及编码始终发生的某些处理步骤。
DSL看起来与SQL非常相似,事实上,我使用berkeley db(通过sqlite3接口)长期存储事件。_这里重要的是事件处理是基于集合的,就像SQL一样。_但是,我得出结论,不应将通用处理逻辑添加到DSL中,而是嵌入lua或lisp来处理此问题。
处理核心基于boost::asio构建,支持多线程,rpc通过协议缓冲区完成,事件使用协议缓冲器IO库进行编码 - 即事件不使用协议缓冲器对象进行结构化,只是使用相同的编码/解码库。我将创建一个包含行的数据集对象,与数据库引擎类似,将在内存中存储集合。DSL中的处理步骤将首先由通用处理逻辑处理,然后再呈现。
无论我使用什么可嵌入脚本环境,我的处理核心中的每个线程都可能需要自己的嵌入式语言环境(如果您正在执行多线程工作,那就是lua要求的)。
问题
目前的选择是lisp ECL和lua。牢记性能和吞吐量是一个强烈的要求,这意味着尽可能减少内存分配是非常希望的:
如果您处于我的位置,您会选择哪种语言?
是否有其他选择要考虑(不建议没有可嵌入实现的语言)。Javascript v8呢?
lisp是否更适合该域?我认为lua和lisp在提供什么方面方面不太相同。叫我出去:D
还应考虑其他属性(例如下面提到的属性)吗?
我断言,任何形式的嵌入式数据库IO(请参见下面的DSL示例以获取上下文)都是脚本语言呼叫的数量级,选择任何一个都不会对总吞吐量添加太多开销。我走在正确的道路上吗? :D
期望的属性
我希望将我的数据集映射到lisp列表或lua表中,我希望最小化冗余数据拷贝。例如,如果两个表具有相同的形状,则将一行从一个数据集添加到另一个数据集应尝试使用引用语义。
我可以保证传递作为输入的数据集在我进行lua/lisp调用时不会更改。如果可能,我希望lua和lisp也强制不更改数据集。
嵌入式调用结束后,数据集应该被销毁,创建的任何引用都需要被替换为拷贝(我猜)。
DSL示例
我附上DSL供您观看,以便您了解我正在努力实现的内容。注意:DSL不显示通用处理。
// Derived Events : NewSession EndSession
NAMESPACE WebEvents
{
SYMBOLTABLE DomainName(TEXT) AS INT4;
SYMBOLTABLE STPageHitId(GUID) AS INT8;
SYMBOLTABLE UrlPair(TEXT hostname ,TEXT scriptname) AS INT4;
SYMBOLTABLE UserAgent(TEXT UserAgent) AS INT4;
EVENT 3:PageInput
{
//------------------------------------------------------------//
REQUIRED 1:PagehitId GUID
REQUIRED 2:Attribute TEXT;
REQUIRED 3:Value TEXT;
FABRRICATED 4:PagehitIdSymbol INT8;
//------------------------------------------------------------//
PagehitIdSymbol AS PROVIDED(INT8 ph_symbol)
OR Symbolise(PagehitId) USING STPagehitId;
}
// Derived Event : Pagehit
EVENT 2:PageHit
{
//------------------------------------------------------------//
REQUIRED 1:PageHitId GUID;
REQUIRED 2:SessionId GUID;
REQUIRED 3:DateHit DATETIME;
REQUIRED 4:Hostname TEXT;
REQUIRED 5:ScriptName TEXT;
REQUIRED 6:HttpRefererDomain TEXT;
REQUIRED 7:HttpRefererPath TEXT;
REQUIRED 8:HttpRefererQuery TEXT;
REQUIRED 9:RequestMethod TEXT; // or int4
REQUIRED 10:Https BOOL;
REQUIRED 11:Ipv4Client IPV4;
OPTIONAL 12:PageInput EVENT(PageInput)[];
FABRRICATED 13:PagehitIdSymbol INT8;
//------------------------------------------------------------//
PagehitIdSymbol AS PROVIDED(INT8 ph_symbol)
OR Symbolise(PagehitId) USING STPagehitId;
FIRE INTERNAL EVENT PageInput PROVIDE(PageHitIdSymbol);
}
EVENT 1:SessionGeneration
{
//------------------------------------------------------------//
REQUIRED 1:BinarySessionId GUID;
REQUIRED 2:Domain STRING;
REQUIRED 3:MachineId GUID;
REQUIRED 4:DateCreated DATETIME;
REQUIRED 5:Ipv4Client IPV4;
REQUIRED 6:UserAgent STRING;
REQUIRED 7:Pagehit EVENT(pagehit);
FABRICATED 8:DomainId INT4;
FABRICATED 9:PagehitId INT8;
//-------------------------------------------------------------//
DomainId AS SYMBOLISE(domain) USING DomainName;
PagehitId AS SYMBOLISE(pagehit:PagehitId) USING STPagehitId;
FIRE INTERNAL EVENT pagehit PROVIDE (PagehitId);
}
}
此项目是博士研究项目的组成部分,是/将成为免费软件。如果您有兴趣与我一起(或为此项目做出贡献),请发表评论:D
原文链接 https://stackoverflow.com/questions/7919763
有几种选项可供实现高性能的嵌入式编译器。其中一种是Mono VM,它自然地带有几十个已经实现在其之上的高质量语言,并且它相当可嵌入(看看Second Life如何使用它)。也可以使用LLVM-看起来你的DSL不太复杂,因此实现一个特制编译器不会是什么大问题。
我非常赞同 @jpjacobs 的观点。Lua 是一个非常好的嵌入式语言选择,除非你有非常特殊的需要(例如,如果你的数据特别适合 cons-cell 映射)。
顺便说一下,我用 Lisp 已经很多年了,我非常喜欢 Lisp 的语法,但是现在我通常会选择 Lua。虽然我喜欢 Lisp 的语言,但是我还没有找到一个 Lisp 实现能够像 Lua 一样完美地平衡了功能、小巧和易用性。
Lua:
非常小巧,无论是源代码还是二进制代码,都比许多更受欢迎的语言(例如 Python 等)要小一个数量级或更多。由于 Lua 的源代码非常小和简单,如果你想避免添加外部依赖,则完全可以将整个 Lua 实现包含在你的源代码树中。
非常快。Lua 解释器比大多数脚本语言快很多(再次提醒,常常会比其它脚本语言快一个数量级),LuaJIT2 是一个非常好的 JIT 编译器,可用于一些流行的CPU体系结构(例如 x86、arm、mips、ppc)。使用 LuaJIT 可以将速度提高一倍,而且在许多情况下,结果接近于 C 的速度。LuaJIT 也是标准 Lua 5.1 的 "drop-in" 替换:使用它不需要进行任何应用程序或用户代码的更改。
有 LPEG。LPEG 是一个 "Parsing Expression Grammar" 库,适用于大型和小型任务,允许非常简单、强大和快速的解析;它是 yacc/lex/hairy-regexps 的很好替代品。[我使用 LPEG 和 LuaJIT 编写了一个解析器,比我试图模拟的 yacc/lex 解析器快得多,并且非常容易和直接进行创建。] LPEG 是 Lua 的一个附加包,但是值得获取(它只有一个源文件)。
有一个伟大的 C 接口,使得从 C 调用 Lua 或从 Lua 调用 C 更加愉快。为了接口大型/复杂的 C++ 库,可以使用 SWIG 或任何一个接口生成器(当然,也可以只使用 Lua 的简单 C 接口与 C++ 进行交互)。
拥有自由许可证("类似于 BSD"),这意味着如果你愿意,Lua 可以被嵌入专有项目中,并且对于 FOSS 项目,它与 GPL 兼容。
非常优雅。它并不是 Lisp,因为它不是基于 cons-cell,但是它展示了诸如 Scheme 等语言的明显影响,具有简单而具有吸引力的语法。与 Scheme (至少在早期版本中)类似,它趋向于 "极简主义",但是很好地平衡了可用性。对于有 Lisp 背景(像我一样!)的人来说,Lua 中的很多内容都会很熟悉,尽管存在差异。
非常灵活,例如元表等功能可以轻松地集成领域特定类型和操作。
有一个简单、具有吸引力和易于接近的语法。如果你打算让最终用户编写脚本,这可能并不比 Lisp 对现有 Lisp 用户有什么优势,但可能与他们相关。
专为嵌入式而设计,并且除了其小巧和快速的特点外,还具有各种功能,例如增量 GC,使得在这种上下文中使用脚本语言更加可行。
有着悠久的历史,并且有负责任和专业的开发人员,在过去的二十年中展示了良好的判断力。
拥有一个充满活力和友好的用户社区。
我偶然地参与了一个类似于你的项目的开发,它是一个跨平台的系统,可以在Win-CE,Android和iOS上运行。我需要最大化交叉平台的代码,C / C ++结合可嵌入语言是一个很好的选择。这是我的解决方案,与你的问题有关。
- 如果你处于我的位置,你会选择哪种语言?
我项目中的DSL与你的相似。为了性能,我使用了Yacc / Lex编写了一个编译器,用于将DSL编译为二进制文件以供运行,并编写了一堆API来从二进制文件中获取信息。但是,当DSL语法中有任何修改时,修改编译器和API都非常麻烦。因此,我弃用了DSL,转而使用XML(不要直接编写XML,定义良好的模式是值得的),我编写了一个通用编译器将XML转换为lua表,使用lua重新实现了API。这样做可以获得两个好处:可读性和灵活性,而且没有明显的性能降低。
- 是否有其他备选方案需要考虑(不建议建议没有可嵌入实现的语言)。Javascript v8是个选择吗?
选择lua之前,我考虑了嵌入式Ch(主要用于工业控制系统)、嵌入式Lisp和lua,最终lua脱颖而出,因为lua与C很好地集成在一起,拥有繁荣的社区,对于其他团队成员学习也很容易。关于Javascript v8,如果在嵌入式实时系统中使用,就像用蒸汽锤打碳化的坚果,过于浪费。
- Lisp是否更适合该领域?我认为lua和lisp在提供的功能方面并没有多大区别。指出我的不足之处:D
对于我的领域,Lisp和lua在语义上具有相同的能力,它们都可以轻松处理基于XML的DSL,甚至可以编写一个简单的编译器将XML转换为lisp列表或lua表。它们都可以轻松处理领域逻辑。但是lua与C / C ++更好地集成在一起,这也是lua的目标。
- 是否有其他与以下属性类似的属性应该考虑?
独自工作或与团队成员合作也是解决方案选择的权重因素。如今,熟悉类似于Lisp的语言的程序员并不多。
- 我认为任何形式的嵌入式数据库IO(请参见下面的示例DSL以获取上下文)都会使脚本语言的调用远远超出,选择哪个将不会给整体吞吐量增加太多开销。我的想法正确吗?:D
这里是编程语言性能列表,这里是计算机组件访问时间列表。如果您的系统受IO限制,则脚本的开销不是关键因素。我的系统是一个O&M(运营和维护)系统,脚本性能微不足道。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
您没有提供使用的平台,但如果您的平台能够使用LuaJIT 2,我肯定会选择它,因为执行速度接近编译代码,并且使用FFI库与C代码的接口更容易。
我不知道其他可嵌入的脚本语言,所以我无法真正比较它们能做什么以及它们如何与表格一起工作。
Lua主要使用引用:所有函数、用户数据、表格都通过引用使用,并且在没有对数据的引用时,它们将在下一次gc运行时进行收集。 字符串被内部化,因此某个字符串仅在内存中出现一次。 需要考虑的一点是,应该避免创建并随后丢弃大量的表格,因为这可能会减慢GC循环(正如您引用的Lua gem中所解释的那样)。
对于解析您的代码示例,我建议看看LPEG库。
原文链接:https://stackoverflow.com/questions/20514957/fastest-and-secure-scripting-language-for-embedding-in-c-program