【问题标题】:Does DSL or Java Fluent API design effect the Application performance?DSL 或 Java Fluent API 设计是否会影响应用程序性能?
【发布时间】:2014-09-16 12:47:08
【问题描述】:

如果我使用内部 DSL(领域特定语言)或外部 DSL(领域特定语言)或流畅的 API 设计模式设计应用程序,是否会降低应用程序性能?

【问题讨论】:

  • 这取决于替代方案是什么......你可以编写没有这些性能更低或更高的代码......
  • 外部 DSL 需要一个解析阶段,因此它比通常使用 Fluent API 实现的内部 DSL 慢。
  • 如果使用这些模式设计应用程序,这是否意味着性能没有变化(小变化)?
  • @zafarkhaja 其他人呢,如果使用内部 dsl,我们需要创建比不使用内部 dsl 更多的对象。
  • @user2613486 在内部 DSL 的情况下,它可能需要更多的类和方法,但与解析阶段相比,开销可以忽略不计。

标签: java dsl fluent


【解决方案1】:

与内部 DSL 相比,外部 DSL 可以带来更好的性能和可用性。

DSL 的目的是让工程师简洁明了地指定问题或解决方案,以便他能够更快、更有效地解决问题。

如果问题不需要高性能,可以从一组子例程中构建一个内部 DSL,然后简单地调用它们即可达到预期的效果。值得注意的是,大多数计算并不昂贵,因此是关于“过早优化”的标准警告。

然而,许多 DSL确实需要高性能(SQL、专家系统、词法分析器和解析器生成器)。这些解决方案通常需要复杂的算法(解析、名称解析、流分析、布尔方程构造/简化)来分析工程师提供的 DSL 规范实例,然后应用特殊算法(模式匹配、FSA 构造、Rete 网络)复杂的代码生成和优化(查询优化、特殊情况处理、代码运动、代数简化)以产生有效的答案。在这种情况下,恕我直言,内部 DSL 几乎是一场灾难,因为很难仅对 API 调用进行推理,而无需对与流程纠缠在一起的其他语言进行推理。也很难找到 DSL 规范实例的边界;它在哪里结束,只是简单的编程结束?

一般来说,我认为“外部”DSL,那些具有专门符号(无论是文本还是图形)的 DSL 更容易编写(然后阅读)。在某些情况下,没有符号就无法实现 DSL(考虑 LR 解析器生成器或 Rete 网络;手工编码这些都不实用,您必须拥有外部 DSL 和支持工具)。如果目的是让工程师多次解决问题,我相信可读性和表达性是你应该优化的,而不是易于实现。 SQL 比任何数据库表访问的程序堆更容易阅读。这也是维护的胜利;如果 DSL 取得任何成功,人们就会想要改变他们指定的内容。外部 DSL 的缺点是必须为其设计一个体面的规范符号,这可能并不容易做到或在领域设计师的技能范围内,并且构建支持 DSL 的工具通常被认为是困难的。 (查看我的简历,我有后者的答案)。

内部 DSL 唯一好的论据是它不会被多次使用,因此设计相应的规范语言或支持工具是不值得的。这让我想知道提出的 DSL 的实际效用。

【讨论】:

    【解决方案2】:

    一个小论点 _pro_ 内部 DSL(如果这太过分了,请投反对票。)

    内部 DSL

    内部 DSL 以类型安全的方式构造模型,并且通常带有语义检查。自动完成也有帮助。因此,即使不是应用程序性能,它也有利于软件质量,也就是开发性能。

    现在一个好的 DSL 由构建器类组成,它们构成了一个单独定义的模型。最终的评估,归结为一个结果,可以“编译”。

    Java 在正则表达式 Pattern/Matcher 中使用它,带有 Pattern.compile/matcher。那里没有真正的 DSL,但也是内部正则表达式模型的构建者。

    回顾一下,当模型准备好构建时,它也可以“编译”。有时热点编译器会启动。

    外部 DSL

    但外部 DSL 可能会预编译为更直接的代码,从而省去内部 DSL 的编译和优化。您不能轻易地遵循代码、数据模型和优化。 DSL 的一些努力必须涉及语法着色/语法错误/自动完成。此外,外部 DSL 编译器产生的数据可能比代码多。 “加载器”部分也必须很快。

    内部 DSL 的开销:以及要考虑的内容。

    流畅的 API 和立即构建模型之间的开销并不大。通常return this; 用于链式调用,最好在final(不可覆盖)方法中完成,以便编译器可以立即优化,而不是依赖于热点编译器的检测。语义检查是不可避免的开销:错误是有问题的,不需要隐藏它们。如果它们导致代码迭代,则您正在构建的数据结构可能是错误的(= 使用映射)。所以开销应该足够小。

    我个人的结论是 DSL 有利于开发,而且速度足够快。通常下一步是有问题的。 jOOQ 很好,JPA 标准 API 很好,ORM 有一些问题。 Java 8 的 lambda 也是如此。看到它们用作 DSL,很有趣,而且可能只是过于间接,过度劳累。

    目前,DSL 仅应用于几个领域:技术接口,如 java+SQL,但实际上并不需要它。以及开发人员有时将责任转移给最终客户的业务逻辑,例如编程、版本控制、登台。 (更改后的业务规则会立即对生命系统生效,表单编辑器。)这些业务 DSL 的效率取决于系统背后有一个复杂的语义模型,例如数据库引擎。效率低下是由于声明/程序不匹配造成的。

    代码跨语言的统一可以部分深入; Java + SQL:Java 将 java 存储过程传递给 SQL。矢量处理可能相同。

    附言

    .NET 有一些跨/混合语言编译器工作(我认为 Irony)来生成令牌流、AST 并从那里开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-12
      • 2021-07-05
      • 2019-09-30
      • 1970-01-01
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多