python 基于文件的程序需要时间来执行

python file based program taking time to execute

我创建了以下脚本,根据用户输入处理两个文件并生成第三个结果文件。

脚本可以正常执行,没有任何问题,但是当两个文件的计数都很高时,就会花费时间。在我的测试期间,我测试了具有 500000 条记录的 InputFile-1 和具有 100 条记录的 InputFile-2。

所以想检查是否有任何优化的可能性来减少整体执行时间。请分享您的想法!

提前致谢。

import ipaddress
filePathName1 = raw_input('InputFile-1 : ')
filePathName2 = raw_input('InputFile-2: ')

ipLookupResultFileName = filePathName1 + ' - ResultFile.txt'
ipLookupResultFile = open(ipLookupResultFileName,'w+')

with open(filePathName1,'r') as ipFile:
    with open(filePathName2,'r') as ipCidrRangeFile:
        for everyIP in ipFile:
            ipLookupFlag = 'NONE'
            ipCidrRangeFile.seek(0)
            for everyIpCidrRange in ipCidrRangeFile:
                if (ipaddress.IPv4Address(unicode(everyIP.rstrip('\n'))) in ipaddress.ip_network(unicode(everyIpCidrRange.rstrip('\n')))) == True:
                    ipLookupFlag = 'True'
                    break
            if ipLookupFlag == 'True':
                ipLookupResultFile.write(everyIP.rstrip('\n') + ' - Valid_Operator_IP' + '\n')
            else:
                ipLookupResultFile.write(everyIP.rstrip('\n') + ' - Not_Valid_Operator_IP' + '\n')

ipFile.close()
ipCidrRangeFile.close()
ipLookupResultFile.close()

InputFile-1 的示例记录: 192.169.0.1 192.169.0.6 192.169.0.7

InputFile-2 的示例记录:

192.169.0.1/32
192.169.0.6/16
255.255.255.0/32
255.255.255.0/16
192.169.0.7/32

ResultFile.txt 的示例记录:

192.169.0.1 - Not_Valid_Operator_IP
192.169.0.6 - Valid_Operator_IP
192.169.0.7 - Not_Valid_Operator_IP

起点是要关注的是,对于 ipFile 中的每一行,您都重新读取了 ipCidrRangeFile。而是将 ipCidrRangeFile 读入列表或其他集合,然后在循环中从那里读取。

with open(filePathName2,'r') as ipCidrRangeFile:
    ipCidrRangeList = ipCidrRangeFile.readlines()

with open(filePathName1,'r') as ipFile:
    with open(filePathName2,'r') as ipCidrRangeFile:
        for everyIP in ipCidrRangeList :
            ipLookupFlag = 'NONE'
            ipCidrRangeFile.seek(0)
            for everyIpCidrRange in ipCidrRangeFile:
                if (ipaddress.IPv4Address(unicode(everyIP.rstrip('\n'))) in ipaddress.ip_network(unicode(everyIpCidrRange.rstrip('\n')))) == True:
                    ipLookupFlag = 'True'
                    break
            if ipLookupFlag == 'True':
                ipLookupResultFile.write(everyIP.rstrip('\n') + ' - Valid_Operator_IP' + '\n')
            else:
                ipLookupResultFile.write(everyIP.rstrip('\n') + ' - Not_Valid_Operator_IP' + '\n')

更好的方法是对每个文件加载并处理一次,然后使用此数据进行处理:

filePathName1 = raw_input('InputFile-1 : ')
filePathName2 = raw_input('InputFile-2: ')

ipLookupResultFileName = filePathName1 + ' - ResultFile2.txt'

with open(filePathName1) as ipFile:
    ip_addresses = [unicode(ip.strip()) for ip in ipFile]

with open(filePathName2) as ipCidrRangeFile:  
    ip_cidr_ranges = [unicode(cidr.strip()) for cidr in ipCidrRangeFile]

with open(ipLookupResultFileName,'w+') as ipLookupResultFile:
    for ip_address in ip_addresses:
        ipLookupFlag = False
        for cidr_range in ip_cidr_ranges:
            if ipaddress.IPv4Address(ip_address) in ipaddress.ip_network(cidr_range):
                ipLookupFlag = True
                break

        if ipLookupFlag:
            ipLookupResultFile.write("{} - Valid_Operator_IP\n".format(ip_address))
        else:
            ipLookupResultFile.write("{} - Not_Valid_Operator_IP\n".format(ip_address))

注意,使用 with() 意味着您之后不需要明确关闭文件。

根据您的需要,可以通过删除任何重复项来进一步提高速度 ip_addresses。这可以通过将数据加载到 set() 而不是列表中来完成,例如:

ip_addresses = set(unicode(ip.strip()) for ip in ipFile)

您还可以在将结果写入文件之前按 IP 地址对结果进行排序。