被请求接口中的情况如下: 根据用户输入参数, 需要使用pandas和numpy进行大量计算,这些计算中 ,比如 在 范围 1-100之间使用 随机函数 生成 一个随机值,这个随机值 就是一条线上的点; 这个接口 需要 随机100万次 然后把100万个点渲染到前端页面上;
分析需求: 因为是随机100万次,每次随机值都放在list中,最后发给前端; 每次计算时 不会影响其他程序;
优化思路:
- 可以考虑 把100万次的计算 平均放到 10个进程中;每个进程负责10万次计算; 这样可以缩减10倍时间; 不应该放到线程中,因为此接口瓶颈是 计算密集型任务,放在线程中 由于GIL锁的原因和线程间的来回切换更慢; 如果是 IO密集型任务(提取db数据等等)可以考虑多线程; 技术为:使用多进程的第三方包: joblib;
优化结果: 速度确实快了10倍,但是 每个进程还是要for循环10万次, 继续优化;
优化思路:
- 思路一:多进程用过了,每个进程中如果使用多线程 因为是计算密集型 所以多线程没用; 怎么办,从 代码运行速度上考虑, 如何让numpy跑的更快, 最后发现使用技术为: numba ,此包第一次运行代码时先编译一次,后续运行不再编译,能提升100倍;
- 思路二:用了10个进程,每个进程有点大,可以把机器的所有进程都用到,但是每个进程循环的次数还是很多, 能不能在不换机器的情况下增加并发数; 于是找到了 阿里云的 函数式计算服务, 可以把计算请求发送到阿里云服务,对方用一个机器的一个进程跑 一个随机点的for循环计算函数; 这样 可以 最大化的 增加并发数,可以做到每个计算函数 只跑合理次数的for循环; 但是 阿里云此服务的缺点在于 网络波动较大,以及 目前2-3分钟如果不使用 阿里云 分配的资源 会进行回收,这时 会出现冷启动耗时较长; 且 资金耗费较高;
决定 使用 第一种思路 的 numba进行优化; 结果确实在 2s内完成 接口请求;