`
larlf
  • 浏览: 105649 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

脚本系统:TCC和V8的简单对比

阅读更多
项目中使用V8做为脚本系统,运行速度基本能满足需要,但是有两点问题不太好处理:
一、C++到JS的相互调用及数据类型转换有一定的性能损失
二、GC时的stop-the-world中断时间
这两点基本是无解的。而且发现在最新的V8中,GC的时间不降反升,于是尝试了一下TCC,希望能解决部分问题。

对比方式是用一个简单的相加函数,在脚本中实现,在宿主中调用。

  #include <iostream>
  #include <v8.h>
  #include <dew_utils.h>
  
  using namespace v8;
  
  int main(int argc, char** argv)
  {
      HandleScope scope;
      Persistent<Context> context=Context::New();
      Context::Scope context_sceop(context);
  
      Handle<String> source=String::New("function fun1(a, b) { return a+b; }");
      Handle<Script> script=Script::Compile(source);
      script->Run();
  
      Local<Value> value=context->Global()->Get(String::New("fun1"));
      if(value->IsFunction())
      {
          Local<Function> fun=Local<Function>::Cast(value);
  
          uint64 t1=GameUtils::msTimeStamp();
  
          for(int i=0; i<100000; ++i)
          {
              Handle<Value> argv[2];
              argv[0]=Integer::New(5);
              argv[1]=Integer::New(6);
  
              Local<Value> result=fun->Call(context->Global(), 2, argv);
          }
  
          uint64 t2=GameUtils::msTimeStamp();
          std::cout<<"Result : "<<int(t2-t1)<<std::endl;
      }
  
      context.Dispose();
      return 0;
  }
 


 #include <iostream>
 #include <dew_utils.h>
 #include <stdlib.h>
 #include <iostream>
 #include <dew_utils.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <libtcc.h>
 
 typedef int (*FunType)(int, int);
 
 int main(int argc, char** argv)
 {
     char script[]="void main(int argc, char** argv){} \n int fun1() { return 101; } \n int fun2(int a, int b) { return a+b; }";
 
     TCCState *s;
     s=tcc_new();
     tcc_set_lib_path(s, "/data/lib/tcc-0.9.26");
     tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
     tcc_compile_string(s, script);
     int size=tcc_relocate(s, NULL);
     void* mem=malloc(size);
     tcc_relocate(s, mem);
 
     void* val=tcc_get_symbol(s, "fun1");
     std::cout<<"Val : "<<*((int*)val)<<std::endl;
 
     FunType fun=(FunType)tcc_get_symbol(s, "fun2");
     if(fun)
     {
         uint64 t1=GameUtils::msTimeStamp();
 
         for(int i=0; i<10000000; ++i)
         {
             int a=5, b=6;
             int result=fun(a, b);
         }
 
         uint64 t2=GameUtils::msTimeStamp();
 
         std::cout<<"Result : "<<int(t2-t1)<<std::endl;
     }
 
     return 0;
 }


两种脚本系统中运行时间同为65ms左右,但使用TCC比使用V8的次数多了100倍。这和V8和C++之间相互调用性能不高有很大的关系,同为JIT,相信如果把循环体放在脚本中,差距没有这么严重。

结论:在性能要求比较高的地方,可以考虑用TCC代替V8,以改善本文开始时提到的两点问题。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics