① 【python 】性能優化系列:隨機數
最近在做的項目重點部分與大量生成隨機數有關,維度高達[1700000,10000],需要生成 10 x 30 次左右,這里遇到內存和速度的雙重瓶頸,特地研究了一下如何優化隨機數。
優化時間測試所需的分析工具在另一篇博客《性能優化系列一:分析工具》中提到。
原生的python中也有隨機模塊生成 random.randint 和 random.random 等,但是速度非常慢,numpy 速度可以大幅提升。一般都採用numpy生成隨機數。
比較常用的就是以上幾種。在需要生成大量隨機數的情況下,或生成偽隨機數的情況下,python 3.7 常用 RandomState 。
直接生成大規模非稀疏矩陣如下,經常遇到 MemoryError 的錯誤,大概是同時生成多個float64精度的大規模隨機矩陣伺服器內存不夠,而random state 似乎也沒提供調整類型的attr,
這時最好使用即使生成即使銷毀,僅保留種子作為索引,同樣,多個CPU之間共享大規模矩陣涉及到共享內存或數據傳輸同步較慢的問題,最好也共享seed而不是直接共享矩陣。
ps. 這里注意一般我們設置time.time()為種子時,對於並發性程序是無效的,不要在並發程序中同時定義,建議生成一個seed list 列表再從中取。
這里可以對大規模矩陣進行分片以進行後續的np 乘法,再切片賦值,以時間換內存。這種情況的麻煩在於如果設定隨機數種子會導致每個分片的隨機數相同。可以利用一個最初seed(爺爺種子)randint生成 一組切片組數的seed(父親種子),再每次從中取不同的隨機數。
在上述切片方法嘗試之後,可以解決內存問題。但是時間非常慢,特別是採取s = 1時在standard normal 上調用170萬次的時間長達3000s,line search一下搜索了大約100000為切片值仍然太慢。在文檔中發現了 BitGenerator 和 Generator ,大約可以提速到原來的 1/3。
除了Numpy和基本模塊之外,AES CTR 加密演算法生成隨機數也很快,但是並不能有比較方便的方式控制每次生成的一樣。參見以下reference。
tensorflow 和 pytorch 也都有大規模生成隨機tensor的方式。性能待考。
1. 超快生成隨機數的方式CSDN博客
2. tensorflow 生成隨機tensor