V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
shiyuu
V2EX  ›  Python

求助线程进程问题, IPy 处理 IP 网段

  •  
  •   shiyuu · 2021-09-14 09:31:15 +08:00 · 1574 次点击
    这是一个创建于 1202 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 IPy 模块做 ip 和网段包含的判断 官方样例 from IPy import IP IP('192.168.1.12') in IP('192.168.1.0/24')

    因为 IP 地址和网段很多,所以写了函数

    def ipcompare(): ip_list=[] ip_net=[] result=open(r'D:\Python\IP 地址处理\results.txt',"w+") with open(r'D:\Python\IP 地址处理\iplists.txt','r') as lists: for line in lists: ip_list.append(line.rstrip("\n")) with open(r'D:\Python\IP 地址处理\ipnets.txt','r') as nets: for line in nets: ip_net.append(line.rstrip("\n")) for i in ip_list: for n in ip_net: if IP(i) in IP(n): print(f'{n} nets include ipaddress {i}',file=result)

    这么写的执行好慢,要 25 分钟才出结果 10 万个 IP 地址,400 个网段,相当于要做 100000*400 次套用 IP('192.168.1.12') in IP('192.168.1.0/24') 来做判断 抄了网上几段 threading 和 multiprocessing 来尝试加快执行速度,但是都没有效果 求助大佬,要怎么写才能让执行时间缩短?

    8 条回复    2021-09-14 18:11:59 +08:00
    RRRoger
        1
    RRRoger  
       2021-09-14 09:46:10 +08:00
    先想想能不能优化代码了 你这个循环太多了

    另外你这个是 IO 密集型, 开多线程,基于 GIL 不能用多核,把你的 10w IP 切片处理吧
    RRRoger
        2
    RRRoger  
       2021-09-14 09:52:21 +08:00
    高并发 IO 密集 考虑一下 asyncio
    shiyuu
        3
    shiyuu  
    OP
       2021-09-14 09:52:29 +08:00
    IPy 不能直接做列表对比,不然也不用这么循环一个一个放进去了
    Kinnice
        4
    Kinnice  
       2021-09-14 10:44:32 +08:00
    代码格式化一下
    ch2
        5
    ch2  
       2021-09-14 11:19:37 +08:00
    学一点数据结构跟计网的知识吧,判断 ip 在网段内很简单的
    你把网段做成一个前缀树,这样就不用重复调用 400 次了
    调库改成手动判断
    另外这个不是 io 密集,就是你写的代码复杂度太高了而已
    todd7zhang
        6
    todd7zhang  
       2021-09-14 11:49:26 +08:00
    如果你看下这个的实现 IP('192.168.1.12') in IP('192.168.1.0/24')
    就会发现实际上执行和 '192.168.1.12' in ['192.168.1.0', '192.168.1.1', ..., '192.168.1.254', '192.168.1.255'] 没区别
    那这个实际执行次数就是 10w * 400 * 255

    所以你可以先处理 IP 段 每一行 变成一个 set(str(i) for i in IP('192.168.1.0/24'))
    然后再 '192.168.1.12' in set

    实测 1000 * 400 : IP('192.168.1.12') in IP('192.168.1.0/24') 3.92s
    1000* 400: '192.168.1.12' in set 18.1ms
    mansurx
        7
    mansurx  
       2021-09-14 14:57:05 +08:00
    有个办法是把 IP 转换成十进制、然后网段取第一个 ip 和最后一个 ip 转成一个数值范围,这样再判断效率会很高。ipaddress 模块也可以看看
    MoYi123
        8
    MoYi123  
       2021-09-14 18:11:59 +08:00
    用 pypy,不包含写文件,0.75 秒。
    当然你用字典树优化一下肯定能更快。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2760 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 12:03 · PVG 20:03 · LAX 04:03 · JFK 07:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.