Python大数据处理代码性能优化

在做大数据处理时,可能会涉及到大矩阵运算和并行计算,python原生对这些支持的不是太好,必须要进行优化。
大数据、大矩阵、并行计算时,可以从以下几点对python代码进行优化:

矩阵计算

对向量、矩阵做运算(拼接)时,使用numpy,效率会高于list。

用joblib将numpy格式存储矩阵为’.jl’格式,读入asm opcode 1,2,3,4-gram(8G)数据(格式化为矩阵),只需要20s。改进前数据均存储为.csv格式,读入8G的csv并解析为list of list,需要1122s。

list of list的矩阵,做merge要借助for循环(python原生不支持并行操作),需要120s。改进后,用numpy矩阵,merge时只需要做np.hstack操作,5s就搞定。

Cython

Cython 是包含 C 数据类型的 Python。Cython让你拥有C的数据类型(比py的轻量级)和python的代码结构。

下面是一个普通的python函数。

def fun(r):
    x = 3.1415926*r*r
    y = 2*3.14*r
    return x-y

在正常的python代码中调用它

import calc
import time

start_time = time.time()
for i in range(10000000):
    calc.fun(i)
print('costed {} seconds'.format(time.time() - start_time))

执行main函数耗时4.44s

下面是用Cython改写的代码,注意只是增加了类C的变量声明。

from libc.stdint cimport float

cimport cython

def fun(r):
    cdef float x
    cdef float y

    x = 3.1415926*r*r
    y = 2*3.14*r
    return x-y

在python代码中,调用这个Cython函数。

import time

import pyximport
pyximport.install(
    reload_support=True)
import calc

start_time = time.time()
for i in range(10000000):
    calc.fun(i)
print('costed {} seconds'.format(time.time() - start_time))

用掉3.70s。

multi-process

一些大数据处理操作,比如对10W个文件提feature,就可以用多进程,利用多CPU并行操作加速。

from multiprocessing import Pool

P = Pool(processes=2)
P.apply_async(fun1, (para11, para12))
P.apply_async(fun2, (para21, para22))
P.close()
P.join()

文件压缩存储

压缩存储能节省磁盘空间,但文件读写会耗费更多时间,属于用时间换空间的思路。
joblib提供了直接存取numpy矩阵数据的接口。

下面做一个简单的实验

import joblib as jl
import numpy as np

matrix = np.zeros((10000,10000))

jl.dump(matrix, 'x.jl')#非压缩存储,耗时1.34s,存储763M
jl.dump(matrix, 'x.jl.z')#压缩存储,耗时3.19s,存储3.4M

jl.load('x.jl')#536ms
jl.load('x.jl.z')#1.36s

善用del

用del可以将对象占用内存空间的引用计数值置零(Deletion of a name removes the binding of that name from the local or global namespace)。它并不能让对象占用的内存被回收,但一段内存的引用计数变为零,就说明它可以再次被重新使用了(所以del后,不必要GC介入)。

如果不用del,下面这段代码就可能MemoryError

import numpy as np

matrix1 = np.zeros((60000,100000))
matrix2 = np.zeros((60000,100000))
# using matrix1
# using matrix2

利用del,可以将用完后没必要占用内存的对象删掉,下面的代码对内存耗费就没上面的大。

import numpy as np

matrix1 = np.zeros((60000,100000))
# using matrix1
del matrix1

matrix2 = np.zeros((60000,100000))
# using matrix2
del matrix2
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值