2019

终于还是赶在农历年之前抽时间来写年终总结了。 2019对我而言其实技术上并没有实质性进展,而去年定下的目标,一个也没有完成。 这无疑是一个令人沮丧的事情。虽然前几个月时间在忙其他事情,但根本原因是我的技术进入到了一个瓶颈。 几年前我就已经发现,随着时间的增长,我的技术提高量越来越低。 但像今年这种技术再无一丝实质性进展的情况确实是第一次出现。 仔细反思了一下,技术增长量的降低可能和我自己的学习模式有关。 大部分人学习方向都是向上的,比如学了编程语言,去……

Lua中的函数式编程

最近在用Lua实现Websocket协议时,碰到了一个直击我的思维惯性的弱点的Bug。代码大约如下(实际实现较为复杂,比如还支持wss协议,因此定位到问题也着实花费了一些功夫,毕竟GC的执行是异步的.): --websocket.lua local M = {} local mt = { __index = M, __gc = function(sock) close_via_c_layer(sock[1]) end} function M:connect(url) local ip,port = parse from url local fd = connect_via_c_layer(ip,port); local sock = setmetatable({fd}, mt) return ……

重构登录逻辑

终于又甩掉了一个包袱, 这是我重构完第一句想说的话。 从我入职开始, 就因为这套登录逻辑的复杂性而略为不满, 其间还坑过我一次,但是因为一直勉强能用,所以也没有理由对它动手。 这一次终于因为不能够满足新需求,而让我有理由可以重构这段代码了。 旧的登录流程大致如下: $UST=(uid,session,token) Client-------------AuthServer---------------------GameServer-----------DBProxy *--"账号密码认证" ---> * 检查账号密码, ……

Unity资源管理(续)

上次增加资源半自动释放机制之后,根据log显示已经有30%~40%的资源被释放掉了(大部分为UI资源)。然而内存问题,并没有明显改善。 我们的资源管理是通过一个叫做ABM的模块进行管理的,ABM采用标准的引用计数方案来管理资源和AssetBundle的生命周期。 当使用ABM.load_asset时会首先检查这个资源的引用计数是否为0,如果为0则会触发加载相应AssetBundle操作。 加载AssetBundle时会首先检查AssetBundle的引用计数是否为0,如果不为0则直接将引用计数加1.并将结果返回即可。 如果AssetBu……

谈谈Unity的资源管理

在Unity最佳实践明确指出, 要使用AssetBundle而不是Resources目录来管理资源。 然而,事情并不像Unity官方描述的那么美好。因为使用AssetBundle我们甚至无法实现一个高效易用的,完全自动化资源管理方案。 据Unity官方说,一般有两种方案。 方案一,如果你的游戏是关卡性质的,可以在一个关卡里加载所有AssetBundle,然后在进入下一关卡时,卸载本关卡中加载的所有AssetBundle. 但这种机制似乎只对愤怒的小鸟这种小游戏才适用吧:D。 方案二,如果你的游戏不是关卡类的,那……

一次关于Cache的性能分析

Lua5.4-alpha-rc2 已经发布了好一段时间了, 一直没时间去跑跑看性能如何。最近刚好有空,就跑来看看。结果第一段测试代码就把我惊住了。 --a.lua collectgarbage("stop") local function foo() local a = 3 for i = 1, 64 * 1024 * 1024 do a = i end print(a) end foo() 在 Lua5.3.4 和 Lua5.4-alpha-rc2 上,这段代码运行时间分为0.55,0.42s。 通过`./luac -p -l ./lua ` 可以得知,上段这代码性能热点一定是OP_MOVE,和OP_FORLOOP。因此一定是这两个opco……

历史之2018

2018年已经成为历史,当我想总结一下过去一年的所得时,却发现什么都想不起来。借着过去一年的blog和github,总算可以粗略回溯一下历史。 去年的今天,我定下三个目标: 1. 阅读lua源码,并实现虚拟机 2. 阅读《计算机程序设计艺术》 3. 实现一个软件光栅器 到今天为止,lua源码只完整阅读了GC部分,计算机程序设计艺术几乎等于没看,只有软件光栅器做了个七七八八(但其实连光照都没做完)。 下面来说一说流水帐。 过完农历年后,我先挑了“软件光栅器”来做。 一方面是因为《计算机程……

DC3算法

最近做了一个差量更新工具, 实质就是一个Diff工具。这个Diff工具在本地生成一个patch文件。客户端通过网络下载到本地后,根据本地文件和patch文件来生成最新版本文件。 与传统patch不同的是,为了尽可能的减少网络传输,patch文件需要尽可能的小,并且不需要逆向patch(从版a到版本b生成的patch, 版本b使用这个patch可以还原到版本a). 基于以上考虑,我重新设计了一个二进制patch格式,整个patch文件中有两种Action(分别是COPY, INSERT),大致数据结构如下: struct COPY { ……

移动平台native代码遭遇的坑

最近客户端终于开始运行在移动平台上了(当然,快开发完才开始在移动平台尝试运行,本身就是一件很错误的顺序,然而这并不是我所能控制的),之前在PC平台上完全没问题的代码,开始出现一些诡异的问题。 为了保证客户端和服务器使用绝对相同的逻辑执行流程,我们采用C++来开发一部分native代码同时供客户端和服务端来使用。在迁移到移动平台时,这些native库在IOS和Android平台上出现了不同程度的水土不服。 首次在移动平台就发生了crash,并且只有Android平台会crash, 而IOS可以正常……

从CPU层面谈谈优化

大多数时间,大家都在从设计和算法上优化效率(这类优化往往效果比较明显,比如一个二分查找可以轻易将时间复杂度降低为lg(n))。但是在实现上,却很少有人注重实现效率,而理由是反正每年都会有更高频率的CPU出现,我何必花那个心思呢(Java程序员尤其擅长使用这个理由@_@)。 我个人不是完全同意上面的说辞,在不影响代码的可读性和花费不高的代价下,我习惯性的会写最我当前所知道的性能最高的写法。 在很早以前,我一度只有在编写汇编时才可以计算出汇编条数。随着代码量的增加,……