zoukankan      html  css  js  c++  java
  • userdate和table类型的效率对比

    做cocos2d-x开发的人可能有不少人在实现类时会利用cocos2d-x自己给出的类的实现,也即在luaBinding目录下extern.lua的文件中给出的实现:

    --Create an class.
    function class(classname, super)
        local superType = type(super)
        local cls
    
        if superType ~= "function" and superType ~= "table" then
            superType = nil
            super = nil
        end
    
        if superType == "function" or (super and super.__ctype == 1) then
            -- inherited from native C++ Object
            cls = {}
    
            if superType == "table" then
                -- copy fields from super
                for k,v in pairs(super) do cls[k] = v end
                cls.__create = super.__create
                cls.super    = super
            else
                cls.__create = super
            end
    
            cls.ctor    = function() end
            cls.__cname = classname
            cls.__ctype = 1
    
            function cls.new(...)
                local instance = cls.__create(...)
                -- copy fields from class to native object
                for k,v in pairs(cls) do instance[k] = v end
                instance.class = cls
                instance:ctor(...)
                return instance
            end
    
        else
            -- inherited from Lua Object
            if super then
                cls = clone(super)
                cls.super = super
            else
                cls = {ctor = function() end}
            end
    
            cls.__cname = classname
            cls.__ctype = 2 -- lua
            cls.__index = cls
    
            function cls.new(...)
                local instance = setmetatable({}, cls)
                instance.class = cls
                instance:ctor(...)
                return instance
            end
        end
    
        return cls
    end

    这里是支持lua中类继承自cocos2d-x的类的,这样的继承机制下,实例化出来的对象,其类型是一个userdata,那么类中的所有对象(属性或方法)其实都是被拷贝在了obj这个userdata内,之后的访问也都是在userdata中找。

    上面这样说是因为这里的做法:

    function cls.new(...)
          --instance是一个userdata
          local instance = cls.__create(...)
          -- copy fields from class to native object
          for k,v in pairs(cls) do instance[k] = v end
          instance.class = cls
          instance:ctor(...)
          return instance
    end

    那么这样作的话我们就得考虑一个问题,lua(或tolua++)的实现里,对userdata中的对象访问的速度够快吗?我们来做一个测试:

    ----------------------
    测试代码1(o为table,val为table中变量):

        local o = {}
        o.val = 1
    
        local t1 = os.clock()
        for i = 1, 10000000, 1 do 
            o.val = o.val + 1
        end
        local t2 = os.clock()
    
        print(t2 - t1)

    多次运行,打印纸稳定在0.01数量级。


    ----------------------
    测试代码2(o为userdata,val为userdata中变量):

        local o = cc.Node:create()
        o.val = 1
    
        local t1 = os.clock()
        for i = 1, 10000000, 1 do 
            o.val = o.val + 1
        end
        local t2 = os.clock()
    
        print(t2 - t1)

    多次运行,打印纸稳定在4.0数量级。

    ******************
    测试发现,前者的效率为后者的近400倍,也即在table中访问对象比在userdata中访问,速度有近400倍的提升。

    因此,使用cocos2d-x给出的类的实现,虽然能做到支持继承cocos2d-x中的c++对象,但该机制的性能是值得注意的。

    原因分析(这里只是猜测,因为暂未看lua及tolua++的实现):

    1.tolua++在访问userdata中属性或方法时,会不会是遍历了一边userdata中所有东西然后一个一个比较,得出最后访问的数据的如果是这样,就可以勉强解释这个现象,因为table中访问某对象,是通过对key值的做哈希来访问的,其速度自然比遍历要快多了。
    2.在userdata上增加变量,是由lua层通知c层最终在c层增加的,然后每次访问都要经历一个lua层到c层的过程现在是直接在lua层增加,所以访问时不再需要lua层到c层的交互。
  • 相关阅读:
    python之常用模块
    python 正则
    python 二分法例子及冒泡排序
    python 基础之第十二天(re正则,socket模块)
    python获取系统信息psutil
    python 基础之第十一天(面向对象)
    python 基础之第十天(闭包,装饰器,生成器,tarfile与hashlib模块使用)
    python 基础之第九天
    python 基础之第八天--字典相关
    Python 爬虫监控女神的QQ空间新的说说,实现秒赞,并发送说说内容到你的邮箱
  • 原文地址:https://www.cnblogs.com/damowang/p/4095078.html
Copyright © 2011-2022 走看看