栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

用很少的内存优化我的大数据代码

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用很少的内存优化我的大数据代码

注意:我使用Python 2.x,将其移植到3.x并不难。


我的想法很简单-磁盘空间足够,所以让我们进行一些预处理,然后将大的pickle文件转换为更容易在小块中处理的文件。

制备

为了对此进行测试,我编写了一个小脚本,生成一个类似于您的泡菜文件。我假设您输入的图像是灰度图像,深度为8位,并使用生成了10000个随机图像

numpy.random.randint

该脚本将作为基准,我们可以将其与预处理和处理阶段进行比较。

import numpy as npimport pickleimport timeIMAGE_WIDTH = 600IMAGE_HEIGHT = 600FILE_COUNT = 10000t1 = time.time()with open('data/raw_data.pickle', 'wb') as f:    for i in range(FILE_COUNT):        data = np.random.randint(256, size=IMAGE_WIDTH*IMAGE_HEIGHT, dtype=np.uint8)        data = data.reshape(IMAGE_HEIGHT, IMAGE_WIDTH)        pickle.dump(data, f)        print i,t2 = time.time()print 'nDone in %0.3f seconds' % (t2 - t1)

在测试运行中,此脚本在372秒内完成,生成了约10 GB的文件。

预处理

让我们逐行拆分输入图像-
我们将有600个文件,其中文件

N
包含
N
每个输入图像的行。我们可以使用来将行数据存储为二进制
numpy.ndarray.tofile
(然后使用来加载这些文件
numpy.fromfile
)。

import numpy as npimport pickleimport time# Increase open file limit# See https://stackoverflow.com/questions/6774724/why-python-has-limit-for-count-of-file-handlesimport win32filewin32file._setmaxstdio(1024)IMAGE_WIDTH = 600IMAGE_HEIGHT = 600FILE_COUNT = 10000t1 = time.time()outfiles = []for i in range(IMAGE_HEIGHT):    outfilename = 'data/row_%03d.dat' % i    outfiles.append(open(outfilename, 'wb'))with open('data/raw_data.pickle', 'rb') as f:    for i in range(FILE_COUNT):        data = pickle.load(f)        for j in range(IMAGE_HEIGHT): data[j].tofile(outfiles[j])        print i,for i in range(IMAGE_HEIGHT):    outfiles[i].close()t2 = time.time()print 'nDone in %0.3f seconds' % (t2 - t1)

在测试运行中,此脚本在134秒内完成,生成了600个文件,每个文件600万字节。它使用了约30MB或RAM。

处理中

很简单,只需使用加载每个数组

numpy.fromfile
,然后使用
numpy.median
来获取每个列的中值,将其缩减为单行,并将这些行累加到列表中。

最后,用于

numpy.vstack
重新组装中间图像。

import numpy as npimport timeIMAGE_WIDTH = 600IMAGE_HEIGHT = 600t1 = time.time()result_rows = []for i in range(IMAGE_HEIGHT):    outfilename = 'data/row_%03d.dat' % i    data = np.fromfile(outfilename, dtype=np.uint8).reshape(-1, IMAGE_WIDTH)    median_row = np.median(data, axis=0)    result_rows.append(median_row)    print i,result = np.vstack(result_rows)print resultt2 = time.time()print 'nDone in %0.3f seconds' % (t2 - t1)

在测试运行中,此脚本在74秒内完成。您甚至可以很容易地并行化它,但这似乎不值得。该脚本使用了约40MB的RAM。


给定这两个脚本的线性关系,所用时间也应线性变化。对于50000张图像,预处理大约需要11分钟,最终处理大约需要6分钟。这是在i7-4930K @3.4GHz上,故意使用32位Python。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/661134.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号