一、创建多少线程才是合适的?(java)
1.为啥要用多线程?
因为多线程可以提高程序性能。
2.咋样才是性能好?
度量性能的指标:吞吐量和延迟。
吞吐量:单位时间内能处理的请求数量。比如:你1分钟批改1份作业,你老师1分钟批改10份作业。
延迟:发出这个请求到响应这个请求的时间。比如:老师出了一道题,学神1秒有了思路,学霸3秒,学渣1分钟。
3.该咋办?
想要降低延迟和提高吞吐量。有两条路,优化算法和将硬件性能发挥到极致。
在并发编程中,提升性能的本质就是提升硬件的的利用率,更具体的是I/O的利用率和cpu的利用率。
/* 当然一般人能看到的问题,十有八九被远古大佬处理过。就说说一般人,可以做的。我们需要解决cpu和I/O设备的综合利用率问题。*/
方法1:如果cpu和I/O设备的利用率都很低,那么可以尝试通过增加线程来提高吞吐量。
(在单核的情况下,多线程主要用来平衡cpu和I/O设备)
列举原文中给的例子:
计算1+2+..... +100亿的值,如果在4核的CPU.上利用4个线程执行,
线程A计算[1, 25亿),线程B计算[25亿, 50亿),
线程C计算[50, 75亿), 线程D计算[75亿, 100亿,
之后汇总,那么理论上应该比一一个线程计算[1,100亿快将近4倍,响应时间能够降到25%。
一个线程,对于4核的CPU, CPU的利用率只有25%,而4个线程,则能够将CPU的利用率提高到100%。
4.创建多少线程合适?
对于 CPU 密集型的计算场景,理论上“线程的数量 =CPU核数”就是最合适的。
不过在工程上,线程的数量一般会设置为CPU 核数 +1
理论层面:
(单核)最佳线程数=1+(I/O耗时)/cpu耗时
(多核)最佳线程数=CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]
5.思考
理论给我们提供了思路。但是实际情况中,别忘了线程增加的同时也带来了cpu的消耗。要达到合理的线程数除了需要丰富的知识,还需要丰富的经验和对当前情况的正确认识。
查看电脑的核心数和线程数
二、递归和递推
1.递推:
由前面的子解能解得处后面的子解的规则成为递推关系。
(人话:求斐波那契数,f(1)=1,f(2)=2,f(3)=3,f(4)=5,f(6)=8.......我们可以得出一个简单的式子,
当n大于2,f(n)=f(n-1)+f(n-2)。
像这样的求某个问题,可以由这个问题本身分解出来一些小问题,小问题解决了,大问题也就解决了的叫递推)
要写出递推的代码,一般有以下步骤:
(1)确定递推变量 (上面斐波那契数中,n在变)
(2)建立递推关系 ( f(n)=f(n-1)+f(n-2) )
(3)确定初始条件 ( f(1)=1,f(2)=2 )
(4)递推过程的控制 (一般控制递推的开始和结束)
#include<stdio.h>
void main(){
int k,n,p;
long s,f[50];
printf("求第n个斐波那契数,请输入n \n");
scanf("%d",&n);
f[1]=1;
f[2]=2*p-1;
s=f[1]+f[2];
printf("第%d个斐波那契数为:%ld",n,f[n]);
}
递推难点一般在找到递推式子。
2.递归
递归通过函数或过程调用自身将问题转化为本质相同但规模较小的子问题来求解。
一般来说,递归包含边界条件,递归前进和递归返回段。
#include<stdio.h>
int f(int n){
if(n==1||n==2)
return 1;
else
return f(n-1)+f(n-2);
}
int main(){
int n=4;
printf("第%d个斐波那契数为:%d",n,f(4));
return 0;
}
构造递归一般步骤:构建递归关系,确定递归边界,写出递归函数。
3.对比总结
对比两个代码我们可以看到,明显递归求斐波那契数 比较简洁易懂。这也是递归的优点。
但是哪有那么好的事。
同样操作,我们可以发现不管你算第几个数,递归算法总会求到底,做了许多无用功。因此它的时空复杂度均很高。
递推是写起来比较麻烦,但是递推的时间复杂度比较低。
整数s | 20 | 40 | 60 | 80 | 100 |
划分式个数 | 627 | 37338 | 966467 | 15796476 | 190569292 |
递归时间 | 0 | 10 | 130 | 2143 | 25377 |
递推时间 | 0 | 0 | 0 | 0 | 0 |
(注:表格中的0是指运行非常快,这个极小的时间此处可以当作0)
刚学时觉得这两长得差不多,许多地方可以互相替代。
递归也有它的独特的好处,就是当问题需要求解具体每一步 的过程时,递推就无法实现该功能。比如,汉诺塔展示移动过程,排列组合,整数拆分等。
在计数与求和问题中,两者一般可以互相代替。