Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7 用python读取相对较大的文件需要很多时间_Python 2.7_Large Files - Fatal编程技术网

Python 2.7 用python读取相对较大的文件需要很多时间

Python 2.7 用python读取相对较大的文件需要很多时间,python-2.7,large-files,Python 2.7,Large Files,我有一个265MB的文件和7504527行的文本 此循环需要花费大量时间运行: B = namedtuple("B", ["id", "ch"]) def get_tuple_from_b_string(b_str): return B(int(b_str.split("_")[0]),int(b_str.split("_")[1])) with open("/tmp/file.out") as test_out: for line in test_out:

我有一个265MB的文件和7504527行的文本 此循环需要花费大量时间运行:

B = namedtuple("B", ["id", "ch"])

def get_tuple_from_b_string(b_str):
    return B(int(b_str.split("_")[0]),int(b_str.split("_")[1]))

with open("/tmp/file.out") as test_out:
     for line in test_out:
         if line == '' or not line.startswith("["):
              continue
         bracket_index = line.find(']')
         b_str = line[1:bracket_index]
         content = line[bracket_index+1:]
         b_tuple = get_tuple_from_b_string(b_str)
         if not b_tuple in b_tupled_list:
             continue
         if not b_tuple in b_outputs:
             b_outputs[b_tuple] = ''
             b_outputs[b_tuple] += content+'\n'
我现在正在跑步,19:38分钟后仍然没有结束。
我试图检查流程的范围,并重复以下行:

mmap2(空,3145728,保护读取,保护写入,映射私有,映射匿名, -1,0xff9093fc)=0xFFFFFFF4997000
munmap(0xf678b000、3145728)

但是不同的地址(我认为它没有被卡住,还在读)。
我的问题是

  • 为什么要花很长时间(假设它没有卡住)
  • 如果它卡住了,我怎样才能找到它的位置
文件内容示例:

[1_03]{
[1_03]    "0": {
[1_03]        "interfaces": {
[1_03]            "address": [],
[1_03]            "distribution": [],
[1_03]            "interface": [],
[1_03]            "netmask": []
[1_03]        },

一些性能优化:

def get_tuple_from_b_string(b_str):
    # do not split the string twice, map and unpack the split list at once:
    return B(*map(int, b_str.split("_", 2)))

with open("/tmp/file.out") as test_out:
     for line in test_out:
         # omit superfluous test and reverse if logic to remove the 'continue'
         # (probably more a matter of style than performance though...)
         if line.startswith("["):
             # replace finding plus twice slicing with one slice and a split:
             b_str, content = line[1:].split("]", 2)
             b_tuple = get_tuple_from_b_string(b_str)
             # again reversing the if-logic to omit the 'continue'.
             # maybe this could be sped up using a set, depending on what you're doing...
             if b_tuple in b_tupled_list:
                 # 'a not in b' is more clear than 'not a in b'
                 if b_tuple not in b_outputs:
                     # omit the empty assignment, string concatenation is slow!
                     b_outputs[b_tuple] = content+'\n'

通过这些优化,您应该会变得更快一些。尤其是字符串操作可能是最昂贵的部分,因为字符串是不可变的,每次尝试修改字符串都会导致创建该字符串的副本。这需要时间和内存,在性能关键型脚本中应该避免。

一些性能优化:

def get_tuple_from_b_string(b_str):
    # do not split the string twice, map and unpack the split list at once:
    return B(*map(int, b_str.split("_", 2)))

with open("/tmp/file.out") as test_out:
     for line in test_out:
         # omit superfluous test and reverse if logic to remove the 'continue'
         # (probably more a matter of style than performance though...)
         if line.startswith("["):
             # replace finding plus twice slicing with one slice and a split:
             b_str, content = line[1:].split("]", 2)
             b_tuple = get_tuple_from_b_string(b_str)
             # again reversing the if-logic to omit the 'continue'.
             # maybe this could be sped up using a set, depending on what you're doing...
             if b_tuple in b_tupled_list:
                 # 'a not in b' is more clear than 'not a in b'
                 if b_tuple not in b_outputs:
                     # omit the empty assignment, string concatenation is slow!
                     b_outputs[b_tuple] = content+'\n'

通过这些优化,您应该会变得更快一些。尤其是字符串操作可能是最昂贵的部分,因为字符串是不可变的,每次尝试修改字符串都会导致创建该字符串的副本。这需要时间和内存,在性能关键型脚本中应该避免。

您有许多单独的JSON文档,每行都标记有非JSON前缀。我首先要做的是使用
awk
将文件拆分回多个有效的JSON文件,名为1_03.JSON。然后,我会使用像
ujson
()这样的快速JSON解析器将所有这些内容读入Python。总体而言,这可能要快得多

awk
脚本可能大致如下(轻度测试):


然后只需
glob
Python中的文件,并使用
ujson

进行解析,就可以在每一行中使用非JSON前缀标记许多单独的JSON文档。我首先要做的是使用
awk
将文件拆分回多个有效的JSON文件,名为1_03.JSON。然后,我会使用像
ujson
()这样的快速JSON解析器将所有这些内容读入Python。总体而言,这可能要快得多

awk
脚本可能大致如下(轻度测试):


然后,只需要用Python对文件进行
glob
处理,并使用
ujson

进行解析,因为数据量很大,这需要花费很长时间。我看到你在逐行阅读。相反,请尝试使用
read()
一次读取所有内容,然后逐行迭代。您能给我们看一下文件中的几行示例吗?@AnmolSinghJaggi NO!直接迭代文件对象比将整个文件读取到ram、将其拆分为行并迭代该列表要好。通过使用
read()
可以将整个265MB的数据作为单个字符串加载到内存中。此外,程序在开始处理数据之前正在等待读取完成。如果这个文件只有几GB,而你的RAM比这个小呢?真倒霉!在file对象上迭代,每个循环只读取RAM中的一行,速度更快,内存效率也更高。@Epsilon但是,我认为由于您的代码正在运行,您只是在寻求优化,我建议这个问题可以改为迁移到。@JohnZwinck用一些内容编辑了这个问题,但它是重复的。事实上,这是一个大问题,需要很长时间,因为数据是巨大的。我看到你在逐行阅读。相反,请尝试使用
read()
一次读取所有内容,然后逐行迭代。您能给我们看一下文件中的几行示例吗?@AnmolSinghJaggi NO!直接迭代文件对象比将整个文件读取到ram、将其拆分为行并迭代该列表要好。通过使用
read()
可以将整个265MB的数据作为单个字符串加载到内存中。此外,程序在开始处理数据之前正在等待读取完成。如果这个文件只有几GB,而你的RAM比这个小呢?真倒霉!在file对象上迭代,每个循环只读取RAM中的一行,速度更快,内存效率也更高。@Epsilon但是,我认为由于您的代码正在运行,您只是在寻求优化,我建议这个问题可以改为迁移到。@JohnZwinck用一些内容编辑了这个问题,但它是重复的,事实上它是一个大问题