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

  1. --Create an class.
  2. function class(classname, super)
  3. local superType = type(super)
  4. local cls
  5.  
  6. if superType ~= "function" and superType ~= "table" then
  7. superType = nil
  8. super = nil
  9. end
  10.  
  11. if superType == "function" or (super and super.__ctype == ) then
  12. -- inherited from native C++ Object
  13. cls = {}
  14.  
  15. if superType == "table" then
  16. -- copy fields from super
  17. for k,v in pairs(super) do cls[k] = v end
  18. cls.__create = super.__create
  19. cls.super = super
  20. else
  21. cls.__create = super
  22. end
  23.  
  24. cls.ctor = function() end
  25. cls.__cname = classname
  26. cls.__ctype =
  27.  
  28. function cls.new(...)
  29. local instance = cls.__create(...)
  30. -- copy fields from class to native object
  31. for k,v in pairs(cls) do instance[k] = v end
  32. instance.class = cls
  33. instance:ctor(...)
  34. return instance
  35. end
  36.  
  37. else
  38. -- inherited from Lua Object
  39. if super then
  40. cls = clone(super)
  41. cls.super = super
  42. else
  43. cls = {ctor = function() end}
  44. end
  45.  
  46. cls.__cname = classname
  47. cls.__ctype = -- lua
  48. cls.__index = cls
  49.  
  50. function cls.new(...)
  51. local instance = setmetatable({}, cls)
  52. instance.class = cls
  53. instance:ctor(...)
  54. return instance
  55. end
  56. end
  57.  
  58. return cls
  59. end

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

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

  1. function cls.new(...)
  2. --instance是一个userdata
  3. local instance = cls.__create(...)
  4. -- copy fields from class to native object
  5. for k,v in pairs(cls) do instance[k] = v end
  6. instance.class = cls
  7. instance:ctor(...)
  8. return instance
  9. end

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

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

  1. local o = {}
  2. o.val =
  3.  
  4. local t1 = os.clock()
  5. for i = , , do
  6. o.val = o.val +
  7. end
  8. local t2 = os.clock()
  9.  
  10. print(t2 - t1)

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

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

  1. local o = cc.Node:create()
  2. o.val =
  3.  
  4. local t1 = os.clock()
  5. for i = , , do
  6. o.val = o.val +
  7. end
  8. local t2 = os.clock()
  9.  
  10. 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层的交互。

userdate和table类型的效率对比的更多相关文章

  1. C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比

    using System; using System.Runtime.InteropServices; using System.IO; namespace tx { struct ST { publ ...

  2. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  3. SIMD---SSE系列及效率对比

    SSE(即Streaming SIMD Extension),是对由MMX指令集引进的SIMD模型的扩展.我们知道MMX有两个明显的缺点: 只能操作整数. 不能与浮点数同时运行(MMX使用FPU寄存器 ...

  4. read()/fread()/mmap()执行效率对比

    一. read()/fread()/mmap()执行效率对比 系统调用read.c: #include <sys/types.h> #include <sys/stat.h> ...

  5. string中Insert与Format效率对比、String与List中Contains与IndexOf的效率对比

    关于string的效率,众所周知的恐怕是“+”和StringBuilder了,这些本文就不在赘述了.关于本文,请先回答以下问题(假设都是基于多次循环反复调用的情况下):1.使用Insert与Forma ...

  6. FileInputStream 与 BufferedInputStream 效率对比

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3550158.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  7. java中多种写文件方式的效率对比实验

    一.实验背景 最近在考虑一个问题:“如果快速地向文件中写入数据”,java提供了多种文件写入的方式,效率上各有异同,基本上可以分为如下三大类:字节流输出.字符流输出.内存文件映射输出.前两种又可以分为 ...

  8. golang 浮点数 取精度的效率对比

    需求 浮点数取2位精度输出 实现 代码 package main import ( "time" "log" "strconv" " ...

  9. Snapman系统中TCC执行效率和C#执行效率对比

    Snapman集合了TCC编译器可以直接编译执行C语言脚本,其脚本执行效率和C#编译程序进行效率对比,包括下面4方面: 1.函数执行效率 2.数字转换成字符串 3.字符串的叠加 4.MD5算法 这是C ...

随机推荐

  1. Pjax.js防刷新技术

    自我感觉良好,所以拿出现在自己用的 Pjax.js 分享给大家 当然 这个版本是 经过本人修改后的版本,跟其它 拿过来就用的 不一样 而且区别还不小 大多的 Pjax 都是 跟后台无关的,而这个版本是 ...

  2. java识别简单的验证码

    1.老规矩,先上图 要破解类似这样的验证码: 拆分后结果: 然后去匹配,得到结果. 2.拆分图片 拿到图片后,首先把图片中我们需要的部分截取出来. 具体的做法是,创建一个的和图片像素相同的一个代表权重 ...

  3. WPF开发时光之痕日记本(二)—— MVVM基类

    当我们用MVVM的时候要实现INotifyPropertyChanged,每次都要实现这个接口比较麻烦,所以基类的作用就体现出来了.代码如下: public class ViewModelBase : ...

  4. Codeforces Round #381 (Div. 2) D. Alyona and a tree 树上二分+前缀和思想

    题目链接: http://codeforces.com/contest/740/problem/D D. Alyona and a tree time limit per test2 secondsm ...

  5. java.lang.NoClassDefFoundError: antlr/ANTLRException

    在用Hibernate进行查询时,出现这样的错误:Exception in thread "main" java.lang.NoClassDefFoundError: antlr/ ...

  6. Java设计模式-组合模式(Composite)

    组合模式有时又叫部分-整体模式在处理类似树形结构的问题时比较方便,看看关系图: 直接来看代码: public class TreeNode { private String name; private ...

  7. Hibernate-缓存-并发策略

    当多个并发的事务同时访问持久化层的缓存中的相同数据时,会引起并发问题,必须采用必要的事务隔离措施. 在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题.因此可以设定以下4种类型的并发访问策略,每 ...

  8. Java基础-数据类型int,short,char,long,float,double,boolean,byte

    Java语言是静态类型的(statical typed),也就是说所有变量和表达式的类型再编译时就已经完全确定.由于是statical typed,导致Java语言也是强类型(Strong typed ...

  9. 点击Cell中的按钮时,如何取所在的Cell

    4.点击Cell中的按钮时,如何取所在的Cell:-(void)OnTouchBtnInCell:(UIButton *)Btu{CGPoint point = btn.center;point = ...

  10. Oracle查看锁表

     查看锁表进程SQL语句1: select sess.sid,     sess.serial#,     lo.oracle_username,     lo.os_user_name,     a ...