深圳网站建设营销服务平台,做彩票网站程序违法吗,曹鹏wordpress教程 下载,韩国怎样才能出线首先我们可以确定的是不能用read()与readlines()函数#xff1b;因为如果将这两个函数均将数据全部读入内存#xff0c;会造成内存不足的情况。针对数据按行划分的文件以计算行数为例#xff0c;首先针对几种不同的方法来作比较#xff1a;1、使用for遍历的方法#xff0c…首先我们可以确定的是不能用read()与readlines()函数因为如果将这两个函数均将数据全部读入内存会造成内存不足的情况。针对数据按行划分的文件以计算行数为例首先针对几种不同的方法来作比较1、使用for遍历的方法比较美观网上搜索到八有十九是让你这样做尽管已经很快了但还不是最快的start time.time()with open(dataPath, r) as f:count 0for line in f:count 1print(count)print(time.time() - start)输出50000.093862056732177732、使用readline()模拟遍历发现其实结果和第一种差不多start time.time()with open(dataPath, r) as f:line f.readline()count 1while line:count 1line f.readline()print(count - 1)print(time.time() - start)输出50000.094332218170166023、对比readlines()直接去访问结果却更慢了start time.time()with open(dataPath, r) as f:count 0for line in f.readlines():count 1print(count)print(time.time() - start)输出50000.122236967086791994、不断去检测文件指针位置有的时候我们可能需要读到特定的文件位置就停下就会发现tell()十分耗时start time.time()with open(dataPath, r) as f:count 0while f.tell() datasize:f.readline()count 1;print(count)print(time.time() - start)输出50000.291712999343872075、使用mmap的方法mmap是一种虚拟内存映射文件的方法即将一个文件或者其它对象映射到进程的地址空间实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。通过建立一个文件的内存映射将使用操作系统虚拟内存来直接访问文件系统上的数据而不是使用常规的I/O函数访问数据。内存映射通常可以提供I/O性能因为使用内存映射是不需要对每个访问都建立一个单独的系统调用也不需要在缓冲区之间复制数据实际上内核和用户应用都能直接访问内存是目前测到最快的方法。import mmapstart time.time()with open(dataPath, r) as f:# memory-map the file, size 0 means whole filemap mmap.mmap(f.fileno(), length0, accessmmap.ACCESS_READ)count 0while map.readline():count 1print(count)map.close()print(time.time() - start)输出50000.0238659381866455086、可以不按行读取而是按块读取然后分析\n的个数但这只针对计算行数而论可行但我们真正想要的是按行读取数据所以这里只给出实现方法不进行对比。with open(rd:\lines_test.txt,rb) as f:count 0while True:buffer f.read(1024 * 8192)if not buffer:breakcount buffer.count(\n)print count考虑MPI的情况当文件很大的时候任务又需要并行化的话我们可以将文件拆分成多段去处理例如对于4核的电脑可以让4条进程分别去处理文件不同的部分每条进程读四分之一的数据。但这时候要考虑到分割点不一定刚好是换行符的情况所以我们可以考虑从分割点下一个换行符开始搜索分割点第一个换行符之前的交给前一个进程去处理处理方法如图实现类似from mpi4py import MPIimport platformimport sysimport ioimport osimport mmapsys.stdout io.TextIOWrapper(sys.stdout.buffer, encodingutf-8)comm MPI.COMM_WORLDcomm_size comm.sizecomm_rank comm.rankwith open(filePath, r, encodingutf-8) as f:# Set the file pointer to the beginning of a line after blockSize * rank# Use mmap to run fastermap mmap.mmap(f.fileno(), length0, accessmmap.ACCESS_READ)map.seek(comm_rank * blockSize)if comm_rank ! 0:map.readline()# Each process handle about blocksize lines.blockEnd (comm_rank 1) * blockSize# Use index here to avoid using twice map.tell()index map.tell()while index blockEnd and index dataSize:# line map.readline().translate(None, b\x00).decode()line map.readline().decode(utf-8)index map.tell()try:dosomething(line)except Exception as err:print(err)continue如果不用mmap.tell()改用f.tell()的话效率其差一开始我遇到这种情况的时候是想着自己不断去加len(line)去自己计算文件指针的位置的。但又发现一个问题file.readline()会帮你去除部分字符例如\r\n只会保留\n而mmap.readline()则不会而且试过表示很难总是和f.tell()对不齐。数据按特殊符号划分考虑到可能数据划分点不是\n, 我们可以这样读取def rows(f, chunksize1024, sep|):Read a file where the row separator is | lazily.Usage: with open(big.csv) as f: for r in rows(f): process(row)curr_row while True:chunk f.read(chunksize)if chunk : # End of fileyield curr_rowbreakwhile True:i chunk.find(sep)if i -1:breakyield curr_row chunk[:i]curr_row chunk chunk[i1:]curr_row chunk数据无特定划分方式一种方法是用yielddef read_in_chunks(file_object, chunk_size1024):Lazy function (generator) to read a file piece by piece.Default chunk size: 1k.while True:data file_object.read(chunk_size)if not data:breakyield datawith open(really_big_file.dat) as f:for piece in read_in_chunks(f):process_data(piece)另外一种方法是用iter和一个helper functionf open(really_big_file.dat)def read1k():return f.read(1024)for piece in iter(read1k, ):process_data(piece)