提升javascript程序字符串操作的性能

April 1st, 2010

脚本对字符串的操作方法不同,有时候能很大程度上影响性能
最新研究的结果表明,在脚本引擎中,拼接有意义的单词的性能要远高于无意义的字符串
因此,下面的方法能大大改善性能

  1. var s = "abdesafer"//要拼接复制的无意义字符串
  2. var times = 500; //拼接500份
  3.  
  4. function copyStr(s, t){
  5.     var tok = "fool"; //用有意义的字符串进行拼接
  6.     var r = ""; //拼接后的字符串
  7.     for(var i = 0; i < t; i++){
  8.         r += tok;
  9.     }
  10.     r = r.replace(/fool/g, s); //替换
  11.     return r;
  12. }
  13.  
  14. var d = new Date();
  15. copyStr(s, times);
  16. alert(new Date() - d);

月影 前端技术

协作与沟通

March 28th, 2010

  三月份的web标准化交流会圆满结束。包括这期在内,我也参加过好几期交流会了,每期交流会都有很多的收获,在这里先赞一下所有为交流会付出了努力的组织者和积极参与交流会的同学们,大家真的为了咱web前端做了很有意义的事情。这一期北京141人报名的“盛况”也是对标准化交流会的充分肯定。
  本人一直比较懒,所以以前也很少写什么文字,这一次还是写一点东西吧,不然也太说不过去了,哈哈。
  本期交流会主要谈协作和提高效率的问题,这是个蛮实在的主题,也是个蛮大的话题,对于咱们来说也毫无疑问是非常重要的,毕竟我们自己在工作中离不开与人协作和沟通,而我们的工作效率,也是体现自身价值的一个重要部分。
  在这里我大致整理一些自己有感触的内容吧
  说到沟通技巧,具体大家都谈了很多,我觉得大部分都有道理,崔同学的吃饭理论也给我留下了很深刻的印象。而其实吃饭理论并不仅仅是吃吃饭,谈谈感情,最主要的是建立信任和培养默契。我想起曾经还在学校的时候,参加过一次企业管理的培训,那个老师并不是照搬西方的管理学经验,而是说了东方特色的管理,强调“人”的关系。当然这里并不是说只谈感情拉关系,而是说在基于做事情的规范和原则的基础上,如何建立起人与人乃至团队与团队的信任关系,从而达到目标一致,沟通顺畅,提升工作效率,而又能够让大家更快乐的工作。在沟通上,我自己的经验是充分理解对方,学会转换立场,求同存异,彼此理解,还要充分认同对方的专业领域,更重要的是发自内心的信任对方,而信任必须建立在彼此充分了解的基础上。
  不同的团队有不同的特点,工程师相对来说大部分是具有比较谨慎的特质的,很多时候,他们不是不愿意信任你,而是本能的有一种防范心理,在这种时候,沟通方面要尽量站在他们的立场上,这样才可以得到事半功倍的效果。举一个简单的例子,当你要和后端开发人员沟通并让他们接受一个新的模板约定的时候,试着主要从节省他们工作量的角度去说,而不是从你自己对于模板管理、前后端技术分离或其他技术的角度去说。当然,这是在最初不熟悉的情况下,当他们慢慢发现你说的东西很有道理,也确实能对他们的工作产生价值的时候,信任感在不知不觉之间就已经建立起来了,下来你会发现很多事情就容易得多,你和你的团队也越来越被认同。大多数设计师则是另一种类型,他们不一定像研发那么谨慎,但是对自己的专业领域是非常自信的,在这样的情况下,和设计师沟通最好不要去质疑他们的专业领域,如果你真的对他们的设计结果有疑问,试着用不同的态度去应对,但绝对不要一上来就怀疑他们的设计思路。总的来说,和不同的人沟通有不同的技巧,在会上腾讯的leader也提到了情商问题,这确实是值得关注的。
  在两个团队沟通的时候,如果彼此抱有完全不同的观点甚至目标,应该要把自己的东西先暂时抛在一边,共同来“求同”,而不是尝试彼此说服,那样往往很难有效果。目标要一致,就像两个杯子叠起来盛水,要先把自己杯中的水倒掉。当然这些事情,团队的leader必须要去做,而且要认真去做。沟通是方法是过程,不是目的也不是结果,结果是目标一致,一个大的团队,只有每个小团队乃至每个成员的目标一致,任务清晰,才有成功的可能。
  上面说的其实更多是我自己在团队管理方面的想法,而个人方面,我一直觉得一个人最重要的是有远大的目标。克军总结了专业化,我觉得很有道理,但专业化有一个大前提,就是有目标、有理想。职业和业余不同,业余爱好者可以做他喜欢的,避开他不喜欢的,但职业,有时候就不得不去面对那些业余爱好者可以回避的东西。这和下棋一样,有人问职业棋手和业余棋手最大的区别是什么,我觉得两者最大的区别不在于能力高低,而在于业余棋手可以只下喜欢的棋,而职业棋手在不论多困难的时候都必须独自面对胜负,因为这是职业的代价。如果我们不喜欢一个行业,可以选择转行,但是如果我们决定在把这个行业作为“职业”走下去的话,那么,就必须面对有勇气许多东西,而勇气,应该来源于理想和追求。也许有的同学已经在追求自己的理想,而也许有些同学目前只是在一个暂时的环境里提高自己,但在任何环境里,我觉得都不能丢掉自己的理想和事业心。希望各位同学都工作开心,事业有成~

月影 Uncategorized

检测素数的方法——O(logN)

March 17th, 2010

理论上能快速检测出绝大部分数,除了Carmichaels数。

  1. function expmod(a,exp,m){
  2.     if(0 == exp) return 1;
  3.     if(exp % 2){
  4.         return a * (expmod(a, exp-1,m) % m) % m;
  5.     }else{
  6.         return Math.pow(expmod(a, exp / 2, m) % m, 2) % m;
  7.     }
  8. }
  9.  
  10. function test(n){
  11.     if(n < 2 || n > 2 && !(n % 2)) return false;
  12.  
  13.     for(var i = 0; i < 20 && i < n-1; i++){
  14.         var a = ((n - 1) * Math.random() | 0) + 1;
  15.         if(expmod(a,n,n) != a) return false;
  16.     }
  17.     return true;
  18. }

用erlang实现的话:

  1. test(N) ->
  2.         test_more(20, N, N > 1).
  3.  
  4. test_more(_,_,false) ->
  5.         false;
  6. test_more(0,_,F) ->
  7.         F;
  8. test_more(C,N,true) ->
  9.         A = random:uniform(N - 1),
  10.         test_more(C - 1, N, xmath:pow(A, N) rem N =:= A).

其中xmath:pow是自己写的大整数乘方算法(也是O(logN)复杂度)

月影 Uncategorized

打印正三角形

March 15th, 2010

在屏幕上打印正三角形——O(N)复杂度

  1. function tang(lv){
  2.     function _t(lv){
  3.         return (1 << 2*lv + 1) - 1;
  4.     }
  5.    
  6.     var ret = [],t = 0, s = new Array(lv).join('0');
  7.     for(var i = 0; i < lv - 1; i++){
  8.         var x = _t(i);
  9.         ret.push(s + (x ^ t).toString(2) + s);
  10.         s = s.slice(1);
  11.         t = x << 1;
  12.     }
  13.     ret.push(new Array(lv+1).join('* '));
  14.     return ret;
  15. }
  16.  
  17. document.write(tang(13).join().replace(/,/g,"<br/>").replace(/0/g,"&nbsp;").replace(/1/g,"*"));

上面的可能还只能输出有限的阶数(整数限制),下面的算法直接用字符串:

  1. function tang(lv){
  2.    
  3.     var ret = [],c = '*', s = new Array(lv).join(' '), t = k = '';
  4.     for(var i = 0; i < lv-1; i++){
  5.         ret.push(s + c + t + s);
  6.         s = s.slice(1);
  7.         k = k ? k+'  ' : ' ';
  8.         t = k + c;
  9.     }
  10.     ret.push(new Array(lv+1).join('* '));
  11.     return ret;
  12. }
  13.  
  14. document.write(tang(6).join('<br/>').replace(/ /g,'&nbsp'));

月影 Uncategorized

Fibonacii的O(logN)算法

March 15th, 2010

Fibonacii的算法,用通项公式是O(1),用迭代是O(N),但有没有O(logN)的算法呢?
答案是有:

  1. val(N) ->
  2.         val_iter(N, 1, 0, 0, 1).
  3.  
  4. val_iter(0,_,B,_,_) ->
  5.         B;
  6.  
  7. val_iter(N,A,B,P,Q) ->
  8.         R = N rem 2,
  9.         if R =:= 1 ->
  10.                 val_iter(N - 1, B*Q+A*Q+A*P, B*P+A*Q, P, Q);
  11.            true ->
  12.                 val_iter(N div 2,  A, B, Q*Q+P*P, Q*(2*P+Q))
  13.         end.

月影 Uncategorized

FF的正则表达式神奇的负索引属性

March 10th, 2010

查了各种文档,没发现记载,可能是非正式属性
分别对应于正则表达式对象的6个属性
-1 : source
-2 : global
-3 : ignoreCase
-4 : lastIndex
-5 : multiline
-6 : sticky

比如 /a/[-2] 相当于 (/a/).global

月影 Uncategorized

erlang的尾递归优化

March 10th, 2010

1. 计算 f(n) = f(n-1)+f(n-2)+f(n-3)
2. 倒序列表L

树形递归:

  1. foo(N) when N < 3 ->
  2.         N;
  3. foo(N) ->
  4.         foo(N - 1) + foo(N - 2) + foo(N - 3).

线性迭代(尾递归优化):

  1. foo(N) when N < 3 ->
  2.         N;
  3. foo(N) ->
  4.         foo_iter(0,1,2,N-3).
  5.  
  6. foo_iter(A,B,C,0) ->
  7.         A + B + C;
  8. foo_iter(A,B,C,Count) ->
  9.         foo_iter(B, C, A + B + C, Count - 1).

线性递归

  1. range(N) when N=:=0 ->
  2.         [];
  3. range(N) ->
  4.         [N-1|range(N-1)].

线性迭代(尾递归)

  1. revc(L) ->
  2.         revc_iter([],L).
  3.  
  4. revc_iter(T, []) ->
  5.         T;
  6. revc_iter(T,[H|L]) ->
  7.         revc_iter([H|T],L).

有兴趣的同学可以测一下,效率可不是差一个两个数量级的~

月影 Uncategorized

有趣的“块级作用域”

February 24th, 2010
  1. var i=100;
  2. with({i:0}) for(;i<10;i++){
  3.     alert(i);
  4. }
  5. alert(i);
  1. var i = 100;
  2. ~function(i){
  3.     for(;i<10;i++){
  4.         alert(i);
  5.     }
  6. }(0);
  7. alert(i);

以上两种形式建立块级作用域,当然除了特殊需要很少有人这么去折腾…

月影 Uncategorized

函数式编程 2 —— javascript 1.7

February 23rd, 2010

请使用支持JavaScript1.7以上版本的浏览器运行下面的代码

  1. function perms(list){
  2.     if(list.length)
  3.         return Array.concat.apply(
  4.             [],
  5.             [
  6.                 [O.concat(T) for each(T in I)] 
  7.                     for each([O,I] in list.map(function(o,i) [[o],perms(list.slice(0,i).concat(list.slice(i+1)))]))
  8.             ]
  9.         );
  10.     else
  11.         return [[]];
  12. }
  13.  
  14. alert(perms([1,2,3,4]).join("\n"));

JavaScript语法写Functional还是繁琐,上面的这个,用erlang来写的话只要两行——

  1. perms([]) -> [[]];
  2. perms(L) -> [[H|T] || H<-L, T<-perms(L--[H])].

月影 Uncategorized

函数式编程

February 23rd, 2010

快速排序

  1. //纯算法,仅供研究,其实在浏览器下不快,js递归效率很差
  2. function qsort(arr){
  3.     if(!arr.length) return [];
  4.     var c = arr.shift();
  5.     return qsort(arr.filter(function(o){return o<=c?o:null}))
  6.         .concat([c])
  7.         .concat(qsort(arr.filter(function(o){return o>c?o:null})));
  8. }
  9. var a = [1,4,3,2,5,1,-1,3,2,4.5];
  10. alert(qsort(a));

月影 Uncategorized