Golang和Lua相遇会发生什么

  介绍

这篇文章主要讲解了“Golang和Lua相遇会发生什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang和Lua相遇会发生什么”吧!

在GitHub玩耍时,偶然发现了gopher-lua,这是一个纯Golang实现的Lua虚拟机。我们知道Golang是静态语言,而Lua是动态语言,Golang的性能和效率各语言中表现得非常不错,但在动态能力上,肯定是无法与Lua相比,那么如果我们能够将二者结合起来,就能综合二者各自的长处了(手动滑稽。

在项目Wiki中,我们可以知道gopher-lua的执行效率和性能仅比C实现的绑定差。因此从性能方面考虑,这应该是一款非常不错的虚拟机方案。

<强> Hello World

这里给出了一个简单的Hello World程序。我们先是新建了一个虚拟机,随后对其进行了DoString(…)解释执行Lua代码的操作,最后将虚拟机关闭。执行程序,我们将在命令行看到“你好World"的字符串。

package 主要   import  (   “;github.com/yuin/gopher-lua"   )   func  main (), {   l :=, lua.NewState ()   defer  l.Close ()   if  err :=, l.DoString(“打印(“Hello  World") ');, err  !=, nil  {   恐慌(err)   }   }//,Hello 世界

<强>提前编译

在查看上述DoString(…)方法的调用链后,我们发现每执行一次DoString(…)或DoFile(…),都会各执行一次解析和编译。

func  (ls  * LState), DoString (source 字符串),error  {   if  fn, err :=, ls.LoadString(源);,err  !=, nil  {   return 犯错   },{else    ls.Push (fn)   return  ls.PCall (0,, MultRet,, nil)   }   }   func  (ls  * LState), LoadString (source 字符串),(* LFunction,,错误),{   return  ls.Load (strings.NewReader(源),“& lt; string>“)   }   func  (ls  * LState),加载(reader  io.Reader, name 字符串),(* LFunction,,错误),{   块,,err :=, parse.Parse(读者,,名称)//,…   原型,err :=,编译(块,名称)//,…   }

从这一点考虑,在同份Lua代码将被执行多次(如在http服务器中,每次请求将执行相同Lua代码)的场景下,如果我们能够对代码进行提前编译,那么应该能够减少解析和编译的开销(如果这属于hotpath代码)。根据基准结果,提前编译确实能够减少不必要的开销。

package  glua_test   import  (   “bufio"   “os"   “strings"   lua “;github.com/yuin/gopher-lua"   “;github.com/yuin/gopher-lua/parse"   )//,编译,lua 代码字段   func  CompileString (source 字符串),(* lua.FunctionProto,,错误),{   reader :=, strings.NewReader(源)   块,,err :=, parse.Parse(读者,源)   if  err  !=, nil  {   return  nil,犯错   }   原型,err :=, lua.Compile(块,源)   if  err  !=, nil  {   return  nil,犯错   }   return 原型,nil   }//,编译,lua 代码文件   func  CompileFile (filePath 字符串),(* lua.FunctionProto,,错误),{   文件,,err :=, os.Open (filePath)   defer  file.Close ()   if  err  !=, nil  {   return  nil,犯错   }   reader :=, bufio.NewReader(文件)   块,,err :=, parse.Parse(读者,filePath)   if  err  !=, nil  {   return  nil,犯错   }   原型,err :=, lua.Compile(块,,filePath)   if  err  !=, nil  {   return  nil,犯错   }   return 原型,nil   }   func  BenchmarkRunWithoutPreCompiling (b  * testing.B), {   l :=, lua.NewState ()   for 小姐::=,0;,小姐:& lt;, b.N;,我+ +,{   时间=_  l.DoString ('=a  1, +, 1 ')   }   l.Close ()   }   func  BenchmarkRunWithPreCompiling (b  * testing.B), {   l :=, lua.NewState ()   原型,_ :=, CompileString (“=a  1, +, 1 ')   lfunc :=, l.NewFunctionFromProto(原型)   for 小姐::=,0;,小姐:& lt;, b.N;,我+ +,{   l.Push (lfunc)   时间=_  l.PCall (0,, lua.MultRet,, nil)   }   l.Close ()   }//,美好:达尔文//,goarch: amd64//,包裹:glua//,BenchmarkRunWithoutPreCompiling-8 ,,,,,,,, 100000,,,,,,,,,,,,, 19392, ns/op ,,,,,,,,,, 85626, B/op ,,,,,,,, 67, alloc/op//,BenchmarkRunWithPreCompiling-8 ,,,,,,,,,, 1000000,,,,,,,,,,,,,, 1162, ns/op ,,,,,,,,,,, 2752, B/op ,,,,,,,,, 8, alloc/op//传递//,ok ,,,,, glua ,,, 3.328年代

Golang和Lua相遇会发生什么