0

したがって、cElementTree.iterparseを使用して反復解析する大きなxmlドキュメント(ファイルサイズ> 100 mb)を想像してみましょう。

しかし、インテルが私たちに約束したすべてのコアは価値があると思います。どのようにそれらを使用するのでしょうか。これが私が欲しいものです:

from itertools import islice
from xml.etree import ElementTree as etree

tree_iter = etree.iterparse(open("large_file.xml", encoding="utf-8"))

first = islice(tree_iter, 0, 10000)
second = islice(tree_iter, 10000)

parse_first()
parse_second()

これにはいくつかの問題があるようです。特に、iterparse()によって返されるイテレータがスライスに抵抗するように見えることです。

大きなxmlドキュメントの解析ワークロードを2つまたは4つの別々のタスクに分割する方法はありますか(ドキュメント全体をメモリにロードせずに?目的は別々のプロセッサでタスクを実行することです)。

4

1 に答える 1

0

これには、タスク キューを備えた適切なスレッドプールが必要だと思います。私はこの非常に良いものを見つけました(そして使用します)(それはpython3にありますが、2.xに変換するのはそれほど難しくないはずです):

# http://code.activestate.com/recipes/577187-python-thread-pool/

from queue import Queue
from threading import Thread

class Worker(Thread):
    def __init__(self, tasks):
        Thread.__init__(self)
        self.tasks = tasks
        self.daemon = True
        self.start()

    def run(self):
        while True:
            func, args, kargs = self.tasks.get()
            try: func(*args, **kargs)
            except Exception as exception: print(exception)
            self.tasks.task_done()

class ThreadPool:
    def __init__(self, num_threads):
        self.tasks = Queue(num_threads)
        for _ in range(num_threads): Worker(self.tasks)

    def add_task(self, func, *args, **kargs):
        self.tasks.put((func, args, kargs))

    def wait_completion(self):
        self.tasks.join()

これで、iterparse でループを実行するだけで、スレッドプールに作業を分割させることができます。それを使用するのは次のように簡単です:

def executetask(arg):
    print(arg)

workers = threadpool.ThreadPool(4) # 4 is the number of threads
for i in range(100): workers.add_task(executetask, i)

workers.wait_completion() # not needed, only if you need to be certain all work is done before continuing
于 2011-01-22T12:24:37.230 に答える