Groovy性能

3

你好, 我们将要开始一个CRUD项目。 我有一些使用Groovy的经验, 我认为这是正确的工具。 我的担心在于性能。 与Java解决方案相比,Groovy有多好。 据估计,我们最多可以有100个同时用户。 我们将使用MySql数据库和Tomcat服务器。

有任何评论或建议吗?

谢谢


为了澄清我的问题,困境在于应该采用哪种技术。Groovy on grails、Jboss seam还是一些特别开发的技术。对于一个有50到100个同时用户的应用程序,Groovy on grails的性能是否成为问题? - Luixv
2
你还需要澄清“同时”的含义。你是期望在同一秒内进行100个动作点击,还是在任何时候只有100个HTTP会话?(后者可能意味着每秒5次点击) - cherouvim
我们的客户已经定义了同时使用应用程序的用户数量,即最多100个用户同时在线。也就是说,最多有100个HTTP会话。期待您的评论。 - Luixv
4个回答

9
我最近在Groovy性能方面的回答上收到了五个负面评价(!); 然而,我认为确实需要客观事实。就个人而言,我认为使用Groovy和Grails是有成效和有趣的; 然而,确实存在需要解决的性能问题。
网络上有许多基准比较,包括this one。你永远不能相信单一的基准测试(并且引用的这个甚至远远不够科学),但你会有所了解。
Groovy强烈依赖于运行时元编程。在Groovy中,每个对象(除了Groovy脚本)都继承自GroovyObject,其中包含invokeMethod(..)方法。例如,在调用Groovy类中的方法时,方法不会像Java一样直接被调用,而是通过调用前面提到的invokeMethod(..)来调用(它执行了许多反射和查找操作)。
此外,每个GroovyObject都有一个关联的MetaClass。方法调用等概念类似。
与Java相比,还有其他因素降低了Groovy的性能,包括原始数据类型的装箱和(可选的)弱类型,但运行时元编程的上述概念至关重要。您甚至不能想象使用Groovy进行JIT编译器,将Java字节码编译为本地代码以加速执行。
为了解决这些问题,有 Groovy++ 项目。你只需在 Groovy 类上注释 @Typed,它们就会被 (真正的) Java 字节码 静态地 编译。然而,不幸的是,我发现 Groovy++ 还不够成熟,与主要的 Groovy 线和 IDE 集成不好。此外,Groovy++ 违反 基本的 Groovy 编程范例。此外,Groovy++ 的 @Typed 注释不递归工作,也就是说,不影响底层库,如 GORM 或 Grails 控制器基础结构。

我猜你也在考虑使用 Grails 项目。

在查看 Grails 的 GORM 时,该框架大量使用运行时元编程,直接使用 Hibernate,应该表现更好。

在控制器或(尤其是)服务级别,可以将广泛的计算外部化到 Java 类中。但是,在典型的 CRUD 应用程序中,GORM 的比例更高。

在Grails中,潜在的性能问题通常通过在数据库级别上设置缓存层或避免调用服务或控制器方法来解决(参见SpringCache插件Cache Filter插件)。这些通常是建立在Ehcache基础架构之上的。
显然,缓存可能非常适合静态数据,而不是经常更改的(数据库)数据或相当可变的Web输出。
最后,您可以“投入硬件”。 :-)
总之,在大规模网站中使用Groovy / Grails的最决定性因素应该是缓存是否符合特定网站的性质。
编辑: 至于Java的JIT编译器是否有机会介入...... 一个简单的Groovy类
class Hello {
    def getGreeting(name) {
        "Hello " + name
    }
}

被编译成

public class Hello
  implements GroovyObject
{
  public Hello()
  {
    Hello this;
    CallSite[] arrayOfCallSite = $getCallSiteArray();
  }
  public Object getGreeting(Object name) { 
    CallSite[] arrayOfCallSite = $getCallSiteArray(); 
    return arrayOfCallSite[0].call("Hello ", name);
  }

  static
  {
    Long tmp6_3 = Long.valueOf(0L);
    __timeStamp__239_neverHappen1288962446391 = (Long)tmp6_3;
    tmp6_3;
    Long tmp20_17 = Long.valueOf(1288962446391L);
    __timeStamp = (Long)tmp20_17;
    tmp20_17;
    return;
  }
}

这只是冰山一角。活跃的 Groovy 开发者 Jochen Theodoru 这样说:
在 Groovy 中,方法调用通常由多个普通的方法调用组成,其中参数存储在一个数组中,必须检索参数的类,生成一个键,使用哈希表查找方法,如果失败,则必须测试可用的方法以查找兼容的方法,根据运行时类型选择一个方法,为哈希图创建一个键,最后对该方法进行反射式调用。
我真的不认为 JIT 会内联这种动态、高度复杂的调用。
至于你问题的“解决方案”,没有“这样做就可以了”。相反,任务是识别比其他因素更关键的因素和可能的替代方案和缓解策略,评估它们对当前用例的影响(“我能接受吗?”),最后确定最符合要求的技术组合(但并非完全)。

谢谢你的回答。我指的是Groovy on Grails,据我所知它执行JIT编译。尽管如此,如果解决方案是增加更多硬件,那么问题还没有得到解决。对你的回答点赞。 - Luixv

3
在Web应用程序的上下文中,“性能”是您的应用程序的一个方面,而不是您使用的框架/语言的方面。关于方法调用速度、反射速度以及调用经过的框架层数的讨论和比较完全无关紧要。您不是在实现Photoshop滤镜、分形或光线追踪器,而是在实现基于Web的CRUD。
您的阻碍可能是低效的数据库设计、N+1查询(如果使用ORM),全表扫描等。
回答您的问题:使用任何您感到更有信心的现代语言/ Web框架,并专注于正确的架构/设计来解决手头的业务问题。

我不同意语言/框架是无关紧要的观点。虽然我没有任何数据支持,但是那些大量使用反射的动态语言可能会对性能产生影响,而当系统有许多用户时,这种影响会被放大。即使是相同的简单CRUD应用程序,如果用Java编写,也可以处理比用动态语言编写时更多的用户。 - Andrew Eisenberg
方法调用比I/O(文件访问、网络访问、数据库操作)快几个数量级。因此,对于Web应用程序来说,Java可能在4纳秒内进行运行时分派,而Ruby则需要40纳秒,这并不起任何作用。担心这一点是把精力放在了错误的方向上。 - cherouvim

0

50到100个活跃用户并不算太多的流量。只要您正确缓存页面,mysql查询正确索引,您应该没问题。

这是我在地下室运行的一个站点,使用了一台价值1000美元的服务器,它是用Grails编写的。 请自行检查性能 http://www.ewebhostguide.com

注意:有时Comcast连接会中断,网站可能会出现故障。但这只会持续几分钟。在地下室运行网站的缺点。


0
感谢您的答案和建议。我喜欢Groovy。在某些情况下可能会有一些性能问题。Groovy++可能是一个更好的选择。此时,我更愿意给“spring roo”一个机会,它与Groovy有很大的重叠,但您仍然保持在Java中,并且没有将roo.jar添加到您的项目中。因此,您不需要支付任何额外费用来使用它。 此外,“roo”允许反向工程和往返工程。 不幸的是,插件库目前相当小。
路易斯

Groovy现在非常快,而Grails也非常出色。请查看:http://stackoverflow.com/questions/4912444/groovy-poor-multithreading-performance-and-slow-calculations-comparing-to-java/6007036#6007036 - Wanderson Santos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接