介绍
这篇文章主要讲解了“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相遇会发生什么