Skip to content

Trigger 2.0 Benchmarks

Jathan McCollum edited this page Feb 8, 2016 · 8 revisions

Performance Benchmarking Results

Trigger Core (1.5.5)

Code

#!/usr/bin/env python

import collections
import time
from trigger.netdevices import NetDevices
from trigger.cmds import Commando


nd = NetDevices()


class Benchmark(Commando):
    commands = ['show version']


if __name__ == '__main__':
    devices = nd.match(model='3172TQ', site='sjc')
    bencher = Benchmark(devices=devices, verbose=True, max_conns=40)

    start_time = time.time()
    bencher.run()
    end_time = time.time()
    elapsed_time = end_time - start_time

    print 'Elapsed time: %s sec' % elapsed_time

    errors = collections.defaultdict(list)
    for device, err in bencher.errors.iteritems():
        msg = err.type
        errors[msg].append(device)

    print "Error stats:"
    for typ, errs in errors.items():
        print typ, len(errs)

Results

Elapsed time: 18.356867075 sec

Error stats:

In [1]: len(devices)
Out[1]: 119

Twisted + NAPALM

Code

#!/usr/bin/env python

"""
Simple test of using Trigger + Twisted + NAPALM
"""


import time
from twisted.internet import task, defer, threads
from trigger.netdevices import NetDevices


NUM_JOBS = 40

nd = NetDevices()


@defer.inlineCallbacks
def execute_napalm(device, command, results):
    """Execute a command on a device using Napalm."""
    print '[%s] Open.' % device
    yield threads.deferToThread(device.open)
    result = yield threads.deferToThread(device.run_command, command)
    print '[%s] Close.' % device
    yield threads.deferToThread(device.close)

    defer.returnValue(result)


def store_result(result, results, device):
    print '[%s] Done.' % device
    results[device.nodeName] = result
    return result


def all_done(_, start_time):
    end_time = time.time()
    print 'Elapsed time: %f sec' % (end_time - start_time)


def main(reactor, devices, command, results):
    """Do stuff and return results."""
    start_time = time.time()
    deferreds = []
    sem = defer.DeferredSemaphore(NUM_JOBS)

    for device in devices:
        print 'Adding to pool: %s', device
        d = sem.run(execute_napalm, device, command, results)
        d.addCallback(store_result, results, device)
        deferreds.append(d)

    dl = defer.DeferredList(deferreds)
    dl.addCallback(all_done, start_time)

    return dl


if __name__ == '__main__':
    devices = nd.match(model='3172TQ', site='sjc')

    results = {}

    from twisted.internet import reactor
    reactor.suggestThreadPoolSize(NUM_JOBS)

    task.react(main, [devices, 'show version', results], reactor)

Results

Elapsed time: 56.624797 sec

In [1]: len(devices)
Out[1]: 119

In [2]: len(results)
Out[2]: 119

Asyncio + NAPALM

Code

#!/usr/bin/env python

"""
Simple test of using Trigger + asyncio + NAPALM
"""

from concurrent.futures import ThreadPoolExecutor
import time
import trollius as asyncio
from trollius import From, Return
from trigger.netdevices import NetDevices


__version = '0.2'


NUM_JOBS = 40

nd = NetDevices()


def run_command(device, command):
    print '[%s] Open.' % device
    device.open()

    result = device.run_command(command)

    device.close()
    print '[%s] Close.' % device

    return result


@asyncio.coroutine
def execute_napalm(device, command, results, sem):
    """Execute a command on a device using Naplam."""
    with (yield From(sem)):

        loop = asyncio.get_event_loop()
        future = loop.run_in_executor(None, run_command, device, command)
        result = yield From(future)

    results[device.nodeName] = result


def main(devices, command):
    """Do stuff and return results."""
    start_time = time.time()
    loop = asyncio.get_event_loop()
    loop.set_default_executor(ThreadPoolExecutor(NUM_JOBS))
    tasks = []
    results = {}
    sem = asyncio.Semaphore(NUM_JOBS)

    for device in devices:
        print 'Adding to pool: %s' % device
        task = asyncio.ensure_future(
            execute_napalm(device, command, results, sem)
        )
        tasks.append(task)

    try:
        loop.run_until_complete(asyncio.wait(tasks))
    finally:
        loop.close()
        end_time = time.time()
        print 'Elapsed time: %f sec' % (end_time - start_time)

    return results


if __name__ == '__main__':
    devices = nd.match(model='3172TQ', site='sjc')

    results = main(devices, 'show version')

Results

Elapsed time: 38.948174 sec

In [1]: len(devices)
Out[1]: 119

In [2]: len(results)
Out[2]: 119

Clone this wiki locally