Groovy表现

Lui*_*ixv 3 mysql performance groovy tomcat

嗨我们将开始一个CRUD项目.我有一些使用groovy的经验,我认为这是正确的工具.我关心的是表现.与java解决方案相比,groovy有多好.据估计,我们可以同时拥有多达100个用户.我们将使用MySql DB和tomcat服务器.

有任何意见或建议吗?

谢谢

rob*_*ert 9

我最近在Groovy性能的答案上收集了五个反对票(!); 但是,我认为应该是,确实是一个需要客观事实.就个人而言,我认为使用Groovy和Grails工作既有效又有趣; 尽管如此,一个需要解决的性能问题.

网上有许多基准比较,包括这一比较.你永远不会相信单一基准(而且引用的基准甚至不是科学的),但你会明白这一点.

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类.但是,GORM在典型CRUD应用中的比例更高.

Grails中的潜在性能通常通过在数据库级别缓存层或通过避免调用服务或控制器方法来解决(请参阅SpringCache插件缓存筛选器插件).这些通常在Ehcache基础架构之上实现.
显然,缓存可以很好地适应静态数据,而不是经常更改的(数据库)数据,或者是相当可变的Web输出.

最后,你可以"向它投掷硬件".:-)

总之,在大型网站中使用Groovy/Grails的最具决定性的因素应该是缓存是否符合特定网站的性质.

编辑: 关于Java的JIT编译器是否有机会介入的问题...
一个简单的Groovy类

class Hello {
    def getGreeting(name) {
        "Hello " + name
    }
}
Run Code Online (Sandbox Code Playgroud)

被编译到

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

这只是冰山一角.Jochen Theodoru,一个活跃的Groovy开发人员,就是这样说的:

Groovy中的方法调用通常由几个常规方法调用组成,其中参数存储在数组中,必须检索参数的类,从中生成一个键,使用hashmap查找方法,如果是失败,然后我们必须测试兼容方法的可用方法,根据运行时类型选择一种方法,为hasmap创建一个键,然后最后做一个像方法调用的反射.

我真的不认为JIT会内联这种动态,高度复杂的调用.

至于你的问题的"解决方案",没有"这样做,你很好".相反,任务是确定有比其他国家和可能的替代方案和减灾战略更关键的因素,以评估他们对你目前的使用情况("我能活呢?")的影响,并最终识别组合最符合要求的技术(不完全).