[Python-Dev] futures API
Brian Quinlan
brian at sweetapp.com
Fri Dec 10 18:41:52 CET 2010
Oops. I accidentally replied off-list:
On Dec 10, 2010, at 5:36 AM, Thomas Nagy wrote:
> --- El jue, 9/12/10, Brian Quinlan escribió:
>> On Dec 9, 2010, at 4:26 AM, Thomas Nagy wrote:
>>
>>> I am looking forward to replacing a piece of code (http://code.google.com/p/waf/source/browse/trunk/waflib/Runner.py#86
>>> )
>> by the futures module which was announced in python 3.2
>> beta. I am a bit stuck with it, so I have a few questions
>> about the futures:
>>>
>>> 1. Is the futures API frozen?
>>
>> Yes.
>>
>>> 2. How hard would it be to return the tasks processed
>> in an output queue to process/consume the results while they
>> are returned? The code does not seem to be very open for
>> monkey patching.
>>
>> You can associate a callback with a submitted future. That
>> callback could add the future to your queue.
>
> Ok, it works. I was thinking the object was cleaned up immediately
> after it was used.
>
>>> 3. How hard would it be to add new tasks dynamically
>> (after a task is executed) and have the futures object never
>> complete?
>>
>> I'm not sure that I understand your question. You can
>> submit new work to an Executor at until time until it is
>> shutdown and a work item can take as long to complete as you
>> want. If you are contemplating tasks that don't complete
>> then maybe you could be better just scheduling a thread.
>>
>>> 4. Is there a performance evaluation of the futures
>> code (execution overhead) ?
>>
>> No. Scott Dial did make some performance improvements so he
>> might have a handle on its overhead.
>
> Ok.
>
> I have a process running for a long time, and which may use futures
> of different max_workers count. I think it is not too far-fetched to
> create a new futures object each time. Yet, the execution becomes
> slower after each call, for example with http://freehackers.org/~tnagy/futures_test.py
> :
>
> """
> import concurrent.futures
> from queue import Queue
> import datetime
>
> class counter(object):
> def __init__(self, fut):
> self.fut = fut
>
> def run(self):
> def look_busy(num, obj):
> tot = 0
> for x in range(num):
> tot += x
> obj.out_q.put(tot)
>
> start = datetime.datetime.utcnow()
> self.count = 0
> self.out_q = Queue(0)
> for x in range(1000):
> self.count += 1
> self.fut.submit(look_busy, self.count, self)
>
> while self.count:
> self.count -= 1
> self.out_q.get()
>
> delta = datetime.datetime.utcnow() - start
> print(delta.total_seconds())
>
> fut = concurrent.futures.ThreadPoolExecutor(max_workers=20)
> for x in range(100):
> # comment the following line
> fut = concurrent.futures.ThreadPoolExecutor(max_workers=20)
> c = counter(fut)
> c.run()
> """
>
> The runtime grows after each step:
> 0.216451
> 0.225186
> 0.223725
> 0.222274
> 0.230964
> 0.240531
> 0.24137
> 0.252393
> 0.249948
> 0.257153
> ...
>
> Is there a mistake in this piece of code?
There is no mistake that I can see but I suspect that the circular
references that you are building are causing the ThreadPoolExecutor to
take a long time to be collected. Try adding:
c = counter(fut)
c.run()
+ fut.shutdown()
Even if that fixes your problem, I still don't fully understand these
numbers because I would expect the runtime to fall after a while as
ThreadPoolExecutors are collected.
Cheers,
Brian
> Thanks,
> Thomas
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20101210/1b45d817/attachment.html>
More information about the Python-Dev
mailing list