Generators ---------- Problem ======= Until 0.5.2 Pyroute2 collected all the responses in a list and returned them at once. It may be ok as long as there is not so many objects to return. But let's say there are some thousands of routes:: $ ip ro | wc -l 315417 Now we use a script to retrieve the routes:: import sys from pyroute2 import config from pyroute2 import IPRoute config.nlm_generator = (sys.argv[1].lower() if len(sys.argv) > 1 else 'false') == 'true' with IPRoute() as ipr: for route in ipr.get_routes(): pass If the library collects all the routes in a list and returns the list, it may take a lot of memory:: $ /usr/bin/time -v python e.py false Command being timed: "python e.py false" User time (seconds): 30.42 System time (seconds): 3.63 Percent of CPU this job got: 99% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:34.09 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 2416472 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 604787 Voluntary context switches: 9 Involuntary context switches: 688 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0 2416472 kbytes of RSS. Pretty much. Solution ======== Now we use generator to iterate the results:: $ /usr/bin/time -v python e.py true Command being timed: "python e.py true" User time (seconds): 18.48 System time (seconds): 0.99 Percent of CPU this job got: 99% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:19.49 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 45132 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 433589 Voluntary context switches: 9 Involuntary context switches: 244 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0 45132 kbytes of RSS. That's the difference. Say we have a bit more routes:: $ ip ro | wc -l 678148 Without generators the script will simply run ot of memory. But with the generators:: $ /usr/bin/time -v python e.py true Command being timed: "python e.py true" User time (seconds): 39.63 System time (seconds): 2.78 Percent of CPU this job got: 99% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:42.75 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 45324 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 925560 Voluntary context switches: 11 Involuntary context switches: 121182 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0 Again, 45324 kbytes of RSS. Configuration ============= To turn the generator option on, one should set ``pyroute2.config.nlm_generator`` to ``True``. By default is ``False`` not to break existing projects.:: from pyroute2 import config from pyroute2 import IPRoute config.nlm_generator = True with IPRoute() as ipr: for route in ipr.get_routes(): handle(route) IPRoute and generators ====================== IPRoute objects will return generators only for methods that employ ``GET_...`` requests like ``get_routes()``, ``get_links()``, ``link('dump', ...)``, ``addr('dump', ...)``. Setters will work as usually to apply changes immediately.