当前位置: 首页 > news >正文

wordpress中接入支付宝怎样优化网站app

wordpress中接入支付宝,怎样优化网站app,用墨刀做网站首页,微信app小程序开发目录 go调用lua安装使用注册表调用栈Data modelGo中调用lua APILua调用go打开Lua内置模块的子集使用Go创建模块示例1#xff08;官方#xff09;示例2 关闭一个运行的lua虚拟机虚拟机之间共享lua字节码 go-lua调优预编译虚拟机实例池模块调用 go调用lua 这里比较下两个比较有… 目录 go调用lua安装使用注册表调用栈Data modelGo中调用lua APILua调用go打开Lua内置模块的子集使用Go创建模块示例1官方示例2 关闭一个运行的lua虚拟机虚拟机之间共享lua字节码 go-lua调优预编译虚拟机实例池模块调用 go调用lua 这里比较下两个比较有名的go-lua包 github.com/Shopify/go-lua和github.com/yuin/gopher-lua是两个Go语言库允许Go程序与Lua脚本进行交互。 以下是这两个库之间的主要区别 Shopify/go-lua: Shopify/go-lua是一个用Go编写的Lua解释器。它旨在提供一个轻量级、易于使用的Go和Lua之间的接口。该项目主要关注简单性和易集成性。它提供了调用Go函数和Lua函数之间的绑定。 yuin/gopher-lua: yuin/gopher-lua是一个更丰富功能且活跃维护的Go语言Lua虚拟机实现。它支持广泛的Lua功能并包含一个标准库涵盖许多常见的Lua功能。这个库允许Go代码执行Lua脚本访问Lua变量并注册Go函数供Lua脚本使用。它提供了更全面的文档和更大的社区相比之下优于github.com/Shopify/go-lua。根据我上次更新的信息yuin/gopher-lua已经有了更近期的更新和改进这表明它的维护活跃性更高。 在选择这些库时请考虑项目的具体要求。如果您需要与Lua进行简单轻量级集成github.com/Shopify/go-lua可能已经足够。另一方面如果您需要一个功能更丰富且持续维护的库支持更广泛的Lua功能github.com/yuin/gopher-lua会是一个更好的选择。 安装 GopherLua supports Go1.9. go get github.com/yuin/gopher-lua使用 GopherLua的API与Lua的运行方式非常相似但是堆栈仅用于传递参数和接收返回值。 Run scripts in the VM. L : lua.NewState() defer L.Close() // 直接执行lua代码 if err : L.DoString(print(hello)); err ! nil {panic(err) }L : lua.NewState() defer L.Close() // 执行lua脚本文件 if err : L.DoFile(hello.lua); err ! nil {panic(err) }调用栈和注册表大小: LState的调用栈大小控制脚本中Lua函数的最大调用深度Go函数调用不计入其中。 LState的注册表实现对调用函数包括Lua和Go函数的栈式存储并用于表达式中的临时变量。其存储需求会随着调用栈的使用和代码复杂性的增加而增加。 注册表和调用栈都可以设置为固定大小或自动大小。 当您在进程中实例化大量的LState时值得花时间来调整注册表和调用栈的选项。 注册表 注册表可以在每个LState的基础上配置初始大小、最大大小和步长大小。这将允许注册表根据需要进行扩展。一旦扩展它将不会再缩小。 L : lua.NewState(lua.Options{RegistrySize: 1024 * 20, // this is the initial size of the registryRegistryMaxSize: 1024 * 80, // this is the maximum size that the registry can grow to. If set to 0 (the default) then the registry will not auto growRegistryGrowStep: 32, // this is how much to step up the registry by each time it runs out of space. The default is 32.}) defer L.Close()如果注册表对于给定的脚本来说太小最终可能会导致程序崩溃。而如果注册表太大将会浪费内存如果实例化了许多LState这可能是一个显著的问题。自动增长的注册表在调整大小时会带来一点点性能损耗但不会影响其他方面的性能。 调用栈 调用栈可以以两种不同的模式运行即固定大小或自动大小。固定大小的调用栈具有最高的性能并且具有固定的内存开销。自动大小的调用栈将根据需要分配和释放调用栈页面从而确保任何时候使用的内存量最小。缺点是每次分配新的调用帧页面时都会带来一点小的性能影响。默认情况下一个LState会以每页8个调用帧的方式分配和释放调用栈帧因此不会在每个函数调用时产生额外的分配开销。对于大多数用例自动调整大小的调用栈的性能影响可能是可以忽略的。 L : lua.NewState(lua.Options{CallStackSize: 120, // this is the maximum callstack size of this LStateMinimizeStackMemory: true, // Defaults to false if not specified. If set, the callstack will auto grow and shrink as needed up to a max of CallStackSize. If not set, the callstack will be fixed at CallStackSize.}) defer L.Close()Data model 在GopherLua程序中所有的数据都是LValue。LValue是一个接口类型具有以下方法 type LValue interface {String() stringType() LValueType// to reduce runtime.assertI2T2 costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).assertFloat64() (float64, bool)// to reduce runtime.assertI2T2 costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).assertString() (string, bool)// to reduce runtime.assertI2T2 costs, this method should be used instead of the type assertion in heavy paths(typically inside the VM).assertFunction() (*LFunction, bool) }实现LValue接口的对象是 Type nameGo typeType() valueConstantsLNilType(constants)LTNilLNilLBool(constants)LTBoolLTrue, LFalseLNumberfloat64LTNumber-LStringstringLTString-LFunctionstruct pointerLTFunction-LUserDatastruct pointerLTUserData-LStatestruct pointerLTThread-LTablestruct pointerLTTable-LChannelchan LValueLTChannel- Go中调用lua L : lua.NewState() defer L.Close() // 加载double.lua if err : L.DoFile(double.lua); err ! nil {panic(err) }if err : L.CallByParam(lua.P{// 获取函数名Fn: L.GetGlobal(double),NRet: 1,Protect: true,}, lua.LNumber(10)); err ! nil {panic(err) } ret : L.Get(-1) // returned value L.Pop(1) // remove received valueLua支持多个参数和多个返回值参数好办用lua.LNumber(123)返回值个数也可以是多个调用CallByParam的时候NRet就是返回参数个数Fn是要调用的全局函数名Protect为true时如果没找到函数或者出错不会panic只会返回err。 **GopherLua的函数调用是通过堆栈来进行的调用前将参数压栈完事后将结果放入堆栈中调用方在堆栈顶部拿结果。**调用完成后要以压栈的方式一个一个取回返回值ret : L.Get(-1)。 fib.lua 脚本内容 function fib(n)if n 2 then return n endreturn fib(n-1) fib(n-2) endpackage mainimport (fmtlua github.com/yuin/gopher-lua )func main() {// 1、创建 lua 的虚拟机L : lua.NewState()defer L.Close()// 加载fib.lua// Calling DoFile will load a Lua script, compile it to byte code and run the byte code in a LState.// 所以DoFile既加载了文件又执行了字节码if err : L.DoFile(fib.lua); err ! nil {panic(err)}// 调用fib(n)err : L.CallByParam(lua.P{Fn: L.GetGlobal(fib), // 获取fib函数引用NRet: 1, // 指定返回值数量Protect: true, // 如果出现异常是panic还是返回err}, lua.LNumber(10)) // 传递输入参数nif err ! nil {panic(err)}// 获取返回结果ret : L.Get(-1)// 从堆栈中扔掉返回结果// 这里一定要注意不调用此方法后续再调用 L.Get(-1) 获取的还是上一次执行的结果// 这里大家可以自己测试下L.Pop(1)// 打印结果res, ok : ret.(lua.LNumber)if ok {fmt.Println(int(res))} else {fmt.Println(unexpected result)} }API Lua调用go LGFunction类型type LGFunction func(*LState) int func main() {L : lua.NewState()defer L.Close()L.SetGlobal(double, L.NewFunction(func(state *lua.LState) int {lv : state.ToInt(1) /* get argument */L.Push(lua.LNumber(lv * 2)) /* push result */// 返回值个数return 1}))// 加载编译执行hello.luaL.DoFile(./hello.lua) }hello.lua中的内容 print(double(100))再来一个案例 package mainimport (fmtlua github.com/yuin/gopher-lua )func Add(L *lua.LState) int {// 获取参数arg1 : L.ToInt(1)arg2 : L.ToInt(2)ret : arg1 arg2// 返回值L.Push(lua.LNumber(ret))// 返回值的个数return 1 }func main() {L : lua.NewState()defer L.Close()// 注册全局函数L.SetGlobal(add, L.NewFunction(Add))// goerr : L.DoFile(main.lua)if err ! nil {fmt.Print(err.Error())return} }main.lua内容 print(add(10,20))打开Lua内置模块的子集 打开Lua内置模块的子集可以通过以下方式实现例如可以避免启用具有访问本地文件或系统调用权限的模块。 func main() {L : lua.NewState(lua.Options{SkipOpenLibs: true})defer L.Close()for _, pair : range []struct {n stringf lua.LGFunction}{{lua.LoadLibName, lua.OpenPackage}, // Must be first{lua.BaseLibName, lua.OpenBase},{lua.TabLibName, lua.OpenTable},} {if err : L.CallByParam(lua.P{Fn: L.NewFunction(pair.f),NRet: 0,Protect: true,}, lua.LString(pair.n)); err ! nil {panic(err)}}if err : L.DoFile(main.lua); err ! nil {panic(err)} }使用Go创建模块 GopherLua除了可以满足基本的lua需要还将Go语言特有的高级设计直接移植到lua环境中使得内嵌的脚本也具备了一些高级的特性 可以使用context.WithTimeout对执行的lua脚本进行超时 可以使用context.WithCancel打断正在执行的lua脚本 多个lua解释器实例之间还可以通过channel共享数据 支持多路复用选择器select 使用Lua作为内嵌脚本的另外一个重要优势在于Lua非常轻量级占用内存极小。 示例1官方 mymodule.go package mainimport lua github.com/yuin/gopher-luavar exports map[string]lua.LGFunction{myfunc: myfunc, }func myfunc(L *lua.LState) int {return 0 }func Loader(L *lua.LState) int {// register functions to the tablemod : L.SetFuncs(L.NewTable(), exports)// 注册name属性到moduleL.SetField(mod, name, lua.LString(value))// returns the moduleL.Push(mod)return 1 }mymain.go package mainimport (./mymodulegithub.com/yuin/gopher-lua )func main() {L : lua.NewState()defer L.Close()L.PreloadModule(mymodule, mymodule.Loader)if err : L.DoFile(main.lua); err ! nil {panic(err)} }main.lua local m require(mymodule) m.myfunc() print(m.name)示例2 在Go语言的实现中当我们将一个函数注册为Lua函数通过L.SetFuncs等方法它会被转换为LGFunction类型这样可以确保与Lua C API兼容。返回的整数值用于指示函数的返回值数量通常用0表示成功1表示出错。 实际上这个整数值在Go的GopherLua实现中没有特别的意义因为Go语言不需要遵循C API规范。但为了与标准的Lua C API保持一致Go的GopherLua库仍然要求注册给Lua的函数遵循这个规范即返回一个整数值。 因此在Go的GopherLua中LGFunction类型一定要有返回值以满足与Lua C API的兼容性需求即使这个返回值在Go代码中可能并没有特别的实际意义。 package mainimport (lua github.com/yuin/gopher-lua )var exports map[string]lua.LGFunction{add: add, }func add(L *lua.LState) int {// 第一个参数firstArg : L.Get(1).(lua.LNumber)// 第二个参数secondArg : L.Get(2).(lua.LNumber)// 返回值L.Push(firstArg secondArg)// 返回值个数return 1 }func Loader(L *lua.LState) int {// register functions to the tablemod : L.SetFuncs(L.NewTable(), exports)// returns the moduleL.Push(mod)return 1 }关闭一个运行的lua虚拟机 L : lua.NewState() defer L.Close() ctx, cancel : context.WithTimeout(context.Background(), 1*time.Second) defer cancel() // set the context to our LState L.SetContext(ctx) err : L.DoString(local clock os.clockfunction sleep(n) -- secondslocal t0 clock()while clock() - t0 n do endendsleep(3) ) // err.Error() contains context deadline exceeded虚拟机之间共享lua字节码 调用DoFile会加载Lua脚本将其编译为字节码并在LState中运行该字节码。 如果您有多个LState都需要运行相同的脚本您可以在它们之间共享字节码这将节省内存。共享字节码是安全的因为它是只读的不会被Lua脚本更改。 // CompileLua reads the passed lua file from disk and compiles it. func CompileLua(filePath string) (*lua.FunctionProto, error) {file, err : os.Open(filePath)defer file.Close()if err ! nil {return nil, err}reader : bufio.NewReader(file)chunk, err : parse.Parse(reader, filePath)if err ! nil {return nil, err}proto, err : lua.Compile(chunk, filePath)if err ! nil {return nil, err}return proto, nil }// DoCompiledFile takes a FunctionProto, as returned by CompileLua, and runs it in the LState. It is equivalent // to calling DoFile on the LState with the original source file. func DoCompiledFile(L *lua.LState, proto *lua.FunctionProto) error {lfunc : L.NewFunctionFromProto(proto)L.Push(lfunc)return L.PCall(0, lua.MultRet, nil) }// Example shows how to share the compiled byte code from a lua script between multiple VMs. func Example() {codeToShare : CompileLua(mylua.lua)a : lua.NewState()b : lua.NewState()c : lua.NewState()DoCompiledFile(a, codeToShare)DoCompiledFile(b, codeToShare)DoCompiledFile(c, codeToShare) }go-lua调优 预编译 在查看上述 DoString(…) 方法的调用链后发现每执行一次 DoString(…) 或 DoFile(…) 都会各执行一次 parse 和 compile 。 func (ls *LState) DoString(source string) error {if fn, err : ls.LoadString(source); err ! nil {return err} else {ls.Push(fn)return ls.PCall(0, MultRet, nil)} }func (ls *LState) LoadString(source string) (*LFunction, error) {return ls.Load(strings.NewReader(source), string) }func (ls *LState) Load(reader io.Reader, name string) (*LFunction, error) {chunk, err : parse.Parse(reader, name)// ...proto, err : Compile(chunk, name)// ... }从这一点考虑在同份 Lua 代码将被执行多次的场景下如果我们能够对代码进行提前编译那么应该能够减少 parse 和 compile 的开销。 package glua_testimport (bufioosstringslua github.com/yuin/gopher-luagithub.com/yuin/gopher-lua/parse )// 编译 lua 代码字段 func CompileString(source string) (*lua.FunctionProto, error) {reader : strings.NewReader(source)chunk, err : parse.Parse(reader, source)if err ! nil {return nil, err}proto, err : lua.Compile(chunk, source)if err ! nil {return nil, err}return proto, nil }// 编译 lua 代码文件 func CompileFile(filePath string) (*lua.FunctionProto, error) {file, err : os.Open(filePath)defer file.Close()if err ! nil {return nil, err}reader : bufio.NewReader(file)chunk, err : parse.Parse(reader, filePath)if err ! nil {return nil, err}proto, err : lua.Compile(chunk, filePath)if err ! nil {return nil, err}return proto, nil }func BenchmarkRunWithoutPreCompiling(b *testing.B) {l : lua.NewState()for i : 0; i b.N; i {_ l.DoString(a 1 1)}l.Close() }func BenchmarkRunWithPreCompiling(b *testing.B) {l : lua.NewState()proto, _ : CompileString(a 1 1)lfunc : l.NewFunctionFromProto(proto)for i : 0; i b.N; i {l.Push(lfunc)_ l.PCall(0, lua.MultRet, nil)}l.Close() }// goos: darwin // goarch: amd64 // pkg: glua // BenchmarkRunWithoutPreCompiling-8 100000 19392 ns/op 85626 B/op 67 allocs/op // BenchmarkRunWithPreCompiling-8 1000000 1162 ns/op 2752 B/op 8 allocs/op // PASS // ok glua 3.328s虚拟机实例池 新建一个 Lua 虚拟机会涉及到大量的内存分配操作如果采用每次运行都重新创建和销毁的方式的话将消耗大量的资源。引入虚拟机实例池能够复用虚拟机减少不必要的开销。 type lStatePool struct {m sync.Mutexsaved []*lua.LState }func (pl *lStatePool) Get() *lua.LState {pl.m.Lock()defer pl.m.Unlock()n : len(pl.saved)if n 0 {return pl.New()}x : pl.saved[n-1]pl.saved pl.saved[0 : n-1]return x }func (pl *lStatePool) New() *lua.LState {L : lua.NewState()// setting the L up here.// load scripts, set global variables, share channels, etc...return L }func (pl *lStatePool) Put(L *lua.LState) {pl.m.Lock()defer pl.m.Unlock()pl.saved append(pl.saved, L) }func (pl *lStatePool) Shutdown() {for _, L : range pl.saved {L.Close()} }// Global LState pool var luaPool lStatePool{saved: make([]*lua.LState, 0, 4), }README 提供的实例池实现但注意到该实现在初始状态时并未创建足够多的虚拟机实例初始时实例数为 0以及存在 slice 的动态扩容问题这都是值得改进的地方这是一个可以提交pr的点。 模块调用 gopher-lua 支持 Lua 调用 Go 模块在 Golang 程序开发中我们可能设计出许多常用的模块这种跨语言调用的机制使得我们能够对代码、工具进行复用。 package mainimport (fmtlua github.com/yuin/gopher-lua )const source local m require(gomodule) m.goFunc() print(m.name) func main() {L : lua.NewState()defer L.Close()L.PreloadModule(gomodule, load)if err : L.DoString(source); err ! nil {panic(err)} }func load(L *lua.LState) int {mod : L.SetFuncs(L.NewTable(), exports)L.SetField(mod, name, lua.LString(gomodule))L.Push(mod)return 1 }var exports map[string]lua.LGFunction{goFunc: goFunc, }func goFunc(L *lua.LState) int {fmt.Println(golang)return 0 }// golang // gomodule
http://www.yutouwan.com/news/496168/

相关文章:

  • 太原市建设厅网站首页网站优化软件排行榜
  • 域名备案网站名称wordpress后台换中文
  • 网站宣传册怎么做修改wordpress数据库
  • 网站服务器端口设置在线网站建设询问报价
  • 乐平市建设局网站企业邮箱在哪查看
  • 有什么网站做的比较高大上重庆企业vi设计公司
  • 网站模板html下载wordpress 文章投票插件
  • 高端网站开发哪里好2023近期舆情热点事件
  • 北京商场关门seo入门培训课程
  • 免费下载软件的网站企业网站建设的一般要素包括
  • 导航栏网站建站公司做的网站费用计入什么科目
  • 做电商网站用什么软件开发制作空间主页网站
  • 做网站app优惠活动的友情链接交易平台源码
  • 宿州银行网站建设重庆营销型网站随做的好
  • 企业网站备案流程wordpress修改主题
  • 微网站分享功能wordpress 如何切换主题
  • 工信网站投诉系统宝安设计网站建设
  • 购物帮做特惠的网站网站能调用一些字体
  • 重庆网站推广公司泉州微信网站开发公司
  • 安康市网站开发wordpress 会员购买插件
  • 海淀区手机网站设计服务6旅游网站制作代码
  • 站酷网设计素材安徽有几家做网站
  • 腾讯云怎么建网站学平面设计好找工作吗
  • 做智能网站深汕特别合作区属于哪个市
  • 用wordpress建一个网站吗上海市人才服务中心网首页
  • 网站的关键词在哪设置谷歌seo专员是指什么意思
  • dw做的网站wordpress noinput
  • 域名如何跟网站绑定网上商城网站开发
  • 重庆建设网站哪个好业务型网站首页
  • 网站费用清单河津网站建设网站建设