为什么80%的码农都做不了架构师?>>>   

手机腾讯网mt2.0目前已经应用在线上案例,在使用的过程中,为了提高增量更新的效率,我们使用编辑距离算法来替代原来的chunk算法,在这个过程中碰到了一个性能问题,我们这里写一下优化方法。

问题: 编辑距离计算需要用一个矩阵来存放2新旧2个版本的字符,这在js文件较少的情况下ok,但是实际情况下很多js(尤其是多个js合并为一个js)的字符都是几万字符的,如果用java定义一个30000*30000的矩阵,基本上就内存溢出了。。。

解决办法: mixDiff:用chunk算法来计算出最长公共字符串,然后用公共字符串将要比较的两个字符串切成 preString+commString+nextString三个块,其中的commString可以用位置数字表示 然后判断preString和nextString的长度是否短于某个设定值,如果短于则走编辑距离算法,否则继续递递归调用mixDiff. 这样最终得到的增量文件的效果是跟单纯调用编辑距离算法的效果一样的,同时也解决了性能问题 流程图如下:

程序伪码:

啥也不说了上代码:

<!-- lang: java -->
public class MixDiff {class LcsItem {public String  srcPre;public String  tarPre;public JSONArray   lcsPos;public String  srcNext;public String  tarNext;
@Override
public String toString() {return "LcsItem [srcPre=" + srcPre + ", tarPre=" + tarPre + ", lcsPos="+ lcsPos.toJSONString() + ", srcNext=" + srcNext+ ", tarNext=" + tarNext + "]";
}}
public MixDiff() {// TODO Auto-generated constructor stub
}
/*** 编辑距离算法* @param source* @param target* @return*/
public JSONArray getDiffEncode(int start,String oldContentStr,String newContentStr){JSONArray jsonArray=lcsDiff(oldContentStr,newContentStr);//System.out.println("diffencode"+jsonArray);for(int i=0;i<jsonArray.size();i++){Object jObj=jsonArray.get(i);if(jObj instanceof JSONArray ){JSONArray jsonObj=(JSONArray)jObj;jsonObj.set(0, (jsonObj.getIntValue(0)+start));}}if(jsonArray.size()==0){JSONArray tempArray=new JSONArray();tempArray.add(start+1);tempArray.add(oldContentStr.length());jsonArray.add(tempArray);}return jsonArray;
}
public JSONArray  lcsDiff(String source,String target){LcsDiff lcsDiff=new LcsDiff();
//System.out.println("lcsdiff:   "+source+" ||||| "+target );return lcsDiff.diff(source, target).getJSONArray("data");
}
/*** * @param source* @param target* @param chunkSize* @return*/
public JSONArray   chunkDiff(String source,String target,int chunkSize){ChunkDiff chunkUtil = new ChunkDiff();JSONObject json=chunkUtil.makeIncDataFile(source, target, chunkSize);return json.getJSONArray("data");}
public LcsItem getLcsStrByChunk(int initStart,String source,String target,int minLen){JSONArray dataArray=chunkDiff(source,target,12);LcsItem lcsStrItem=new LcsItem();JSONArray lcsPosInit=new JSONArray();lcsPosInit.add(-1);lcsPosInit.add(-1);lcsStrItem.lcsPos=lcsPosInit;int maxLen=0;for(int i=0;i<dataArray.size();i++){Object jObj=dataArray.get(i);if(jObj instanceof JSONArray ){JSONArray jsonObj=(JSONArray)jObj;int len=jsonObj.getIntValue(1)*12;int start=jsonObj.getIntValue(0)*12;int end=start+len;if(len>=minLen&&len>maxLen){JSONArray lcsPos=new JSONArray();lcsPos.add(start+1+initStart);lcsPos.add(len);String lcsStr=source.substring(start, end);lcsStrItem.srcPre=source.substring(0,start);lcsStrItem.srcNext=source.substring(end,source.length());lcsStrItem.lcsPos=lcsPos;//System.out.println(lcsStr);int tarStart=target.indexOf(lcsStr);int tarEnd=tarStart+lcsStr.length();lcsStrItem.tarPre=target.substring(0,tarStart);lcsStrItem.tarNext=target.substring(tarEnd,target.length());maxLen=len;}}}return lcsStrItem;
}public JSONArray mixDiff(int start,String source,String target,int lcsMaxLen){int minLen=12;int sourceLen=source.length();int targetLen=target.length();JSONArray reArray=new JSONArray();//如果是if((sourceLen*targetLen<lcsMaxLen*lcsMaxLen)&&(sourceLen*targetLen)>0){return getDiffEncode(start,source,target);}LcsItem lcsStrItem=getLcsStrByChunk(start,source, target, minLen);//System.out.println("lcs::::"+lcsStrItem);if(lcsStrItem.lcsPos.getIntValue(0)==-1){return getDiffEncode(start,source,target);}else{JSONArray preArray=mixDiff(start,lcsStrItem.srcPre,lcsStrItem.tarPre,lcsMaxLen);addMerge(reArray, preArray);JSONArray midArray=new JSONArray();midArray.add(lcsStrItem.lcsPos);addMerge(reArray,midArray);int nextStart=lcsStrItem.lcsPos.getIntValue(0)+lcsStrItem.lcsPos.getIntValue(1)-1 ;JSONArray nextArray=mixDiff(nextStart,lcsStrItem.srcNext,lcsStrItem.tarNext,lcsMaxLen);addMerge(reArray, nextArray);}return reArray;
}
public String merge(String oldContent,JSONObject incData){String reContent="";JSONArray dataArray=incData.getJSONArray("data");for(int i=0;i<dataArray.size();i++){Object jObj=dataArray.get(i);if(jObj instanceof JSONArray){JSONArray jsonObj=(JSONArray)jObj;int start=jsonObj.getIntValue(0)-1;int len=jsonObj.getIntValue(1);//System.out.println("merge lcs:"+oldContent.substring(start,start+len));reContent+=oldContent.substring(start,start+len);}else{reContent+=jObj.toString();}}return reContent;
}
public void addMerge(JSONArray strDataArray,JSONArray addArry){if(strDataArray.size()==0){strDataArray.addAll(addArry);return;}Object jObj=strDataArray.get(strDataArray.size()-1);Object addObj=addArry.get(0);if((jObj instanceof JSONArray )&&(addObj instanceof JSONArray )){JSONArray jsonObj=(JSONArray)jObj;JSONArray addArrayObj=(JSONArray)addObj;if(jsonObj.getIntValue(0)+jsonObj.getIntValue(1)==addArrayObj.getIntValue(0)){jsonObj.set(1, (jsonObj.getIntValue(1)+addArrayObj.getIntValue(1)));strDataArray.addAll(addArry.subList(1, addArry.size()));}else{strDataArray.addAll(addArry);}}else{strDataArray.addAll(addArry);}
}
public String readFile(String file, String encode) {File a = new File(file);StringBuffer strBuffer = new StringBuffer("");;if (a.exists()) {try {FileInputStream fi = new FileInputStream(a);InputStreamReader isr = new InputStreamReader(fi, "utf-8");BufferedReader bfin = new BufferedReader(isr);String rLine = "";while ((rLine = bfin.readLine()) != null) {strBuffer.append(rLine);}bfin.close();} catch (Exception ex) {}}return strBuffer.toString();}private String MD5(String s) {char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F' };try {byte[] btInput = s.getBytes();MessageDigest mdInst = MessageDigest.getInstance("MD5");mdInst.update(btInput);byte[] md = mdInst.digest();int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);} catch (Exception e) {e.printStackTrace();return null;}
}
public JSONObject makeIncDataFromContent(String source,String target){JSONObject resultFile = new JSONObject();resultFile.put("modify", true);resultFile.put("chunkSize",12);resultFile.put("diffAlg", "lcs");JSONArray strDataArray = new JSONArray();if (MD5(source).equals(MD5(target))) {resultFile.put("modify", false);resultFile.put("data", strDataArray);return resultFile;}JSONArray jArray=mixDiff(0,source, target,12);resultFile.put("data", jArray);return resultFile;
}
public JSONObject makeIncDataFromFile(String oldFile, String newFile) {String oldContent = readFile(oldFile, "utf-8");String newContent = readFile(newFile, "utf-8");return makeIncDataFromContent(oldContent,newContent);}
/*** @param args*/
public static void main(String[] args) {String src="define('init',['util','p1'],function(){console.log('dafds init depend on uil p1 ok!'),document.write('init depend on util p2 ok!</br>')}),define('util',[],function(){console.log('ut ok!'),document.write('util ok!</br>')});sadfafds";String target="sdf define('init',['util','p1'],function(){console.log(' int depnd on util sdfs p1 ok 49!'),document.write('init depend on 34 util p2 ok!</br>')}),define('util',[],function(){console.log('util ok!'),document.write('il ok!</br>')});csadf";MixDiff dUtil = new MixDiff();JSONObject json = dUtil.makeIncDataFromFile("/Users/waynelu/nginxhtmls/jetty/webapps/mtwebapp///release/2014071500017///base-2014071500017.js","/Users/waynelu/nginxhtmls/jetty/webapps/mtwebapp///release/2014071600018///base-2014071600018.js");JSONObject json1 = dUtil.makeIncDataFromContent(src,target);System.out.println(json.toJSONString());String mergeContent=dUtil.merge(src,json1);System.out.println(target);System.out.println(mergeContent);if(target.equals(mergeContent)){System.out.println(true);}else{System.out.println(false);}}

}

MT是手机腾讯网前端团队开发维护的一个专注于移动端的、带有增增量更新特色的js模块管理框架 我们的官网是http://mt.tencent.com,https://mtjs.github.io 我们的github:https://github.com/mtjs/mt,如果觉得MT是个靠谱的项目,请给我们star,您的支持是我们最大的动力

转载于:https://my.oschina.net/luyongfugx/blog/300647

手机腾讯网mt2.0增量更新算法优化小记相关推荐

  1. 手机腾讯网前端框架MT2.1.0发布

    为什么80%的码农都做不了架构师?>>>    手机腾讯网前端框架MT2.1.0发布 <h2>主要更新</h2> ---------------------- ...

  2. 免费点亮手机腾讯网图标_不用手机照样点亮

    有的朋友想开通 手机腾讯网图标,但有的朋友手机不能登录GPRS或者没开通业务或者收费太高不忍心上.今天给大家介绍的方法是不需要手机的,具体步骤请往下看.    第一步:打开: http://win.u ...

  3. android增量更新 腾讯,国内率先支持增量更新 腾讯应用宝3.1更快更省

    为了让Android用户更新升级已安装应用的速度更快,更省流量,近日腾讯应用宝继刚刚发布的全新3.0随心版后, V3.1版国内首家率先支持省流量"增量升级"新功能,只要用户安装了旧 ...

  4. 《阿里巴巴Android开发手册》v1.0.1更新,优化部分内容和示例代码

    摘要: 春节余味尚未消,我们为移动开发者准备了一份迟到的新年礼物--<阿里巴巴Android开发手册>,继<阿里巴巴Java开发手册>之后,阿里巴巴开发规范家族又添一丁,「阿里 ...

  5. 基于增量更新的协同过滤

    转载自:http://blog.sina.com.cn/s/blog_68ffc7a40100uec0.html 前面的一篇文章分析了基本的协同过滤算法,协同过滤最大的问题是计算量过大,为了解决这个问 ...

  6. 酷狗音乐盒2012(手机酷狗) V5.2.0(安卓)

    软件名称:酷狗音乐盒2012(手机酷狗) V5.2.0(安卓) 更新时间:2013-04-26 软件大小:2.98 MB 界面语言:简体中文  授权方式:共享软件  运行环境:Win2003,WinX ...

  7. 中国移动:部分 5G 手机可能有网连不上;iOS 13 出现严重漏洞;ReactOS 0.4.12发布 | 极客头条​...

    快来收听极客头条音频版吧,智能播报由标贝科技提供技术支持. 「CSDN 极客头条」,是从 CSDN 网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有 ...

  8. 使用scrapy_redis,实时增量更新东方头条网全站新闻

    存储使用mysql,增量更新东方头条全站新闻的标题 新闻简介 发布时间 新闻的每一页的内容 以及新闻内的所有图片.东方头条网没有反爬虫,新闻除了首页,其余板块的都是请求一个js.抓包就可以看到. 项目 ...

  9. [置顶]使用scrapy_redis,自动实时增量更新东方头条网全站新闻

    存储使用mysql,增量更新东方头条全站新闻的标题 新闻简介 发布时间 新闻的每一页的内容 以及新闻内的所有图片.项目文件结构. 这是run.py的内容 1 #coding=utf-82 from s ...

最新文章

  1. Windows2008 R2下,DCOM配置里的属性灰色不可用的解决方法
  2. 【Python】Excel处理
  3. UA MATH636 信息论5 信道编码定理的证明
  4. [flutter专题]详解AppBar小部件
  5. IP地址不是唯一的吗?为什么路由器的IP地址都是这样的呢?
  6. 在 F5 LTM 上配置数据包过滤
  7. python center函数_数据类型和数据结构(三):字符串(4) 字符串内置函数(1)
  8. MAC安装influxdb和grafana
  9. 极简算法 —— 判断两字符串是否为相同字母的不同顺序组成
  10. html网页文档无法复制粘贴图片,教你处理不能复制粘贴在网页中的详细图文
  11. 西瓜视频(头条)解析并利用IDM工具下载
  12. Android卡顿掉帧问题分析之实战篇
  13. C++第14周项目1 - 动物怎么叫
  14. 头歌--Java面向对象 - String类
  15. vue项目使用vue-amap调用高德地图api详细步骤
  16. SSD1306-7针脚OLED的使用心得
  17. 目标检测+图像分割项目
  18. 性能测试报告模板 V1.0
  19. 深度学习概述-从神经计算角度
  20. 有效防御DDOS和APT攻击

热门文章

  1. Codeforces Round #544 (Div. 3) A.Middle of the Contest
  2. mac 删除 Windows 或 EFI Boot 启动盘的方法
  3. oracle11g-R2静默安装报错[INS-32013]解决方案
  4. java -D參数简化增加多个jar【简化设置classpath】
  5. 一个android应用开发的感悟
  6. Linux中的常用命令
  7. Android用户界面开发:控件集合
  8. 惠普瘦客户机多屏显示T5740
  9. 数据结构C#版笔记--啥夫曼树(Huffman Tree)与啥夫曼编码(Huffman Encoding)
  10. Q-Learning算法学习