场景1:读取大量文件,分析后,合并到一个二进制文件里面。
解决方案:多线程读取各个文件,分析各自写一份二进制缓存文件,最后合并各个缓存文件到一份文件里面。
设: 文件书n,开启线程m,每份文件分析阶段耗时p,每份合并文件耗时q。
逐个读取合并文件耗时:n(p+q);
多线程合并耗时:((n/m)*(p+q))*α+nq (α是与线程m成反比的参数,机器环境影响很大)
成立条件:n(p+q)> ((n/m)*(p+q))*α+nq
解方程: q>(α/(m-α))*p 假设 α=a/m^β=> q>(a/(m^(β+1)-a) *p (a为和机器环境相关的常数)
分析: m=1 >> q> ∞,不成立
m=2 >> q>(a/(2^(β+1)-a) *p
m=3 >> q>(a/(3^(β+1)-a) *p
m=4 >> q>(a/(4^(β+1)-a) *p
可以看出随着线程数量的增长,不等式越来越容易达成,也就是越能够减小时间消耗。
α的变化是不容易预测的,过多的线程对处理效能的影响是相当大的。事实上,在我的代码里拼接二进制文件是个相当快速的过程,而分析阶段往往耗费大量的时间。
程序员的职责就是追求更加优秀的效能,下一步我希望对合并文件阶段进行多线程加速。不过这却是个失败的体验。
场景2:文件n,线程数量m,归并分组文件数量l,合并一份文件耗时p
解决方案:对文件进行分组,对多组进行多线程合并文件,在对合并后的文件进行分组合并,直到不足一组在逐个合并文件。 逐个合并耗时:n*p;
首先计算合并轮次:(假定文件数足量,余数略去)
第一轮:(n/(l*m))*p;
第二轮:(n/((l^2)*m))*(p*l);
第三轮:(n/((l^3)*m))*(p*l^2);.。。。。。
第q轮:(n/((l^q*m))*(p*l(q-1));.。。。。。
分组合并耗时:(n/(l*m))*p*q
分析:
不等式: (n/(l*m))*p*q<n*p >>q<ml;
q满足条件 (n/l^q)逼近l 结合上市 >>(logl n-1)-ml<0,从趋势上看,随着分组l的逐步增加,等式被减数减少,减数增长,等式越来越成立,l最大取到>>log(n)(n-1)-mn<0;n足够大,前面的值趋向1,>>1-mn<0,不等式不成立。所以与不等式(logl n-1)-ml<0不成立。
这种解决方式不成立,效能下降比较厉害。