【问题标题】:asyncIO - for loop to search in a fileasyncIO - for 循环在文件中搜索
【发布时间】:2022-06-22 17:36:30
【问题描述】:

我有一个 CSV 文件,其中有 15000 个 mac 地址,我想找到每个 mac 地址的供应商映射。

我有一个 json 文件,我可以通过 mac 前缀找到所有供应商映射,如下所示: oui.json

 {
   "VendorMapping": [
      {
         "_mac_prefix": "00:00:00",
         "_vendor_name": "XEROX CORPORATION"
      },
      {
         "_mac_prefix": "00:00:01",
         "_vendor_name": "XEROX CORPORATION"
      },
      {
         "_mac_prefix": "00:00:02",
         "_vendor_name": "XEROX CORPORATION"
      },
      {
         "_mac_prefix": "00:00:03",
         "_vendor_name": "XEROX CORPORATION"
      },
      {
         "_mac_prefix": "00:00:04",
         "_vendor_name": "XEROX CORPORATION"
      },
....

我通过在我的 CSV 中创建一个 foo 循环并在 json 中创建一个 foo 循环来开始我的脚本,以便为我的 CSV 的每个 mac 地址找到匹配的供应商映射:

import json
import os
from time import time

start = time()
f = open("oui.json")
data = json.load(f)
file = open("data.csv")
content = file.readlines()[1:]

for line in content:
    mac = line.split(',')[1]
    print(mac)
    for oui in data["VendorMapping"]:
        if mac.upper().startswith(oui["_mac_prefix"]):
            print(oui["_vendor_name"])
            break
print(f'Total time: {time() - start}')

我花了 49 秒来获取所有 mac 地址的所有供应商映射。但我想让它更快。

为此,我决定像这样使用 asyncIO:

import json
import asyncio
import os
from time import time

start = time()
f = open('oui.json')
data = json.load(f)
file = open("api/data.csv")
content = file.readlines()[1:]

tasks = []

async def vendormapping(line):
    mac = line.split(',')[1]
    print(mac)
    for oui in data["VendorMapping"]:
        if mac.upper().startswith(oui["_mac_prefix"]):
            print(oui["_vendor_name"])
            break

async def main():
    for line in content:
        tasks.append(vendormapping(line))
    await asyncio.gather(*tasks)
    
asyncio.run(main())
print(f"All took {time() - start}")

我认为我做错了什么,因为它需要 39 秒才能继续。我期待更快的东西。 有人可以帮我吗?

谢谢,

【问题讨论】:

  • 函数async def vendormapping() 中没有任何异步功能(您没有使用await)。查看oui.json 的结构 - 是"_mac_prefix" 总是格式为XX:XX:XX - 6 位?
  • 我认为 await 仅用于主要功能。我应该如何把它也放在 vendormapping 函数中?不,有时有 8 位或 10 位数字。感谢您的帮助
  • await 通常仅在等待 courotine 时使用(例如 asyncio.sleep 或通过网络发送/接收数据)。在您的vendormapping() 中,我没有看到任何等待的地方。
  • 我建议重构oui.json的结构。例如将其更改为简单映射{'XX:XX:XX': 'Xerox corp.', 'XX:YY:ZZ': 'Xerox corp.', ... }
  • 好的,如果我像这样重构 json,我不知道如何找到与我的 MAC 地址匹配的密钥。那么在这种情况下我还需要在新的 json 中创建一个 for 循环吗?

标签: python json python-asyncio


【解决方案1】:

asyncio 是单线程 IO。即使你是异步的,你实际上并没有并行处理任何东西。当您的工作负载涉及大量等待时,更多使用 AsyncIO。在这种情况下,无需等待。它只是纯粹的吞吐量。

我已重构您的代码以改用多处理。这比 AsyncIO 更适合原始吞吐量。在我的测试中,我将时间从 15 秒缩短到 4 秒。(使用我猜的欺骗数据)

def vendormapping(line):
    mac = line.split(',')[1]
    print(mac)
    for oui in data["VendorMapping"]:
        if mac.upper().startswith(oui["_mac_prefix"]):
            print(oui["_vendor_name"])
            break


def main():
    with Pool() as p:
        p.map(vendormapping, content)


if __name__ == '__main__':
    main()
    print(f"All took {time() - start}")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多