第89章 七千万次的小石头(4/8)
内存占用:正常。
cpU 占用率,却在几个特定的脚本执行时,反复拉高到100%,红得刺眼。
程序并没有卡死,终端里的进度条还在走。
但它比江临预期的慢,慢得非常不合理。
对于现实世界里的大多数数据科学家或者量化研究员来说,遇到这个情况,第一反应绝对是,机器不够强。
“老板,我们要买更好的 cpU,换 Amd 的线程撕裂者。”
“要加更大的内存,把数据全塞进内存里。”
“上AwS云服务器,开个 124 核的实例并行跑。”
用硬件的暴力去掩盖软件的低效,这是和平年代,资源充沛环境下的通病。
但这不是江临的第一反应。
在他的脑海深处,那个属于【废土世界】的倒计时始终存在。
在资源枯竭的废土里,永远没有再买一台的选项。
在那里,机器慢,不能先要资源,必须先问。
为什么慢?
是什么在吃掉算力?
江临果断按下了 ctrl+c,停掉了后续的扫描任务。
打开python的性能分析工具,将刚才那段跑得极慢的代码用cprofile 重新包起来,然后接入SnakeViz进行可视化分析。
二十分钟后,一份详细的调用栈火焰图出现在屏幕上。
真正的瓶颈浮出水面。
在调用栈里吞掉最多墙钟时间的怪物,不是那些几百万行的大矩阵乘法。
不是复杂的hdF5文件读取,不是前端渲染的图表生成,也不是某个玄学的机器学习复杂模型。
而是几个小得近乎不起眼的动作:排序、排名、分桶。
在量化回测中,经常需要在特定的行业特定的市值区间内,对股票的因子暴露值进行中性化和排序。
每次参与排序的股票可能不多,只有五个、八个、或者十六个。
单独看,给五个数排序,不管用什么算法,每一次都快得像没有成本,连一毫秒都不需要。
但问题在于乘数效应。
qF-oLdLIb-001里有四百多个因子。
三年历史版本。
多个动态调整的样本池。
多种回测配置。
每一天,每一个行业,每一个状态标记、每一个数据版本,都要切出一层层的横截面进行分组排名。
于是,这些微小的小动作被嵌套在庞大的循环网里,被反复调用。
江临把调用栈里耗时最高的那个函数次数打印了出来
七千八百四十二万一千九百零六次。
看着这个天文数字,他沉默了十几秒,然后在项目的audit_log.
md里,他敲下了这样一段话。
本章未完,请翻下一页继续阅读.........