Source

python-hs-benchmark / test.py

Full commit
#!/usr/bin/env python

import time
import random
import sys


global options

def run_test(func, name):
    global options
    
    if not options.quiet:
        sys.stdout.write(name + ': ')
        sys.stdout.flush()
        
    start_time = time.time()
    try:
        func()
    except:
        if options.quiet:
            print >> sys.stderr, name + ': ',
        print >> sys.stderr, "failed or not supported"
        if options.verbose:
            import traceback; traceback.print_exc()
            
        return 0
    else:
        end_time = time.time()
        if not options.quiet:
            print "%f seconds" % (end_time - start_time)
        return end_time - start_time


class BigObject(object):
    def __init__(self, letter='1', size=10000):
        self.object = letter * size

    def __eq__(self, other):
        return self.object == other.object


class Benchmark(object):
    def __init__(self, module, options, key_prefix = ''):
        self.total_time = 0

        self.module = module
        self.options = options
        self.key_prefix =  key_prefix
        self.init_server()
        self.test_set()
        self.test_set_get()
        self.test_pure_get()
        self.test_random_get()
        self.test_set_same()
        self.test_set_big_object()
        self.test_set_get_big_object()
        self.test_set_big_string()
        self.test_set_get_big_string()
        self.test_get()
        self.test_get_big_object()
        self.test_get_multi()
        self.test_p_app_get()
        
        #self.test_get_list()

    def init_server(self):
        self.mc = self.module.Client([self.options.server_address])
        self.mc.set(self.key_prefix + 'bench_key', "E" * 50)

        num_tests = self.options.num_tests
        self.keys = [(self.key_prefix + 'key%d') % i for i in xrange(num_tests)]
        self.values = ['value%d' % i for i in xrange(num_tests)]
        self.random_keys = [(self.key_prefix + 'key%d') % random.randint(0, num_tests) for i in xrange(num_tests * 3)]

    def test_set(self):
        set_ = self.mc.set
        pairs = zip(self.keys, self.values)

        def test():
            for key, value in pairs:
                set_(key, value)
        def test_loop():
            for i in range(10):
                for key, value in pairs:
                    set_(key, value)
        self.total_time += run_test(test, 'test_set')

        for key, value in pairs:
            self.mc.delete(key)

    def test_set_get(self):
        set_ = self.mc.set
        get_ = self.mc.get
        pairs = zip(self.keys, self.values)

        def test():
            for key, value in pairs:
                set_(key, value)
                result = get_(key)
                assert result == value
        self.total_time += run_test(test, 'test_set_get')

        for key, value in pairs:
          self.mc.delete(key)

    def test_pure_get(self):
        set_ = self.mc.set
        get_ = self.mc.get
        pairs = zip(self.keys, self.values)

        for key, value in pairs:
            set_(key, value)

        def test():
            for i in range(100):
                for key, value in pairs:
                    result = get_(key)
                    assert result == value


        self.total_time += run_test(test, 'test_pure_get')

        for key, value in pairs:
          self.mc.delete(key)


    def test_random_get(self):
        get_ = self.mc.get
        set_ = self.mc.set

        value = "chenyin"

        def test():
            index = 0
            for key in self.random_keys:
                result = get_(key)
                index += 1
                if(index % 5 == 0):
                    set_(key, value)
        self.total_time += run_test(test, 'test_random_get')

    def test_set_same(self):
        set_ = self.mc.set

        def test():
            for i in xrange(self.options.num_tests):
                set_(self.key_prefix + 'key', 'value')
        def test_loop():
            for i in range(10):
                for i in xrange(self.options.num_tests):
                    set_(self.key_prefix + 'key', 'value')
        self.total_time += run_test(test, 'test_set_same')

        self.mc.delete(self.key_prefix + 'key')

    def test_set_big_object(self):
        set_ = self.mc.set
        # libmemcached is slow to store large object, so limit the
        # number of objects here to make tests not stall.
        pairs = [((self.key_prefix + 'key%d') % i, BigObject()) for i in xrange(100)]

        def test():
            for key, value in pairs:
                set_(key, value)

        self.total_time += run_test(test, 'test_set_big_object (100 objects)')

        for key, value in pairs:
            self.mc.delete(key)

    def test_set_get_big_object(self):
        set_ = self.mc.set
        get_ = self.mc.get
        # libmemcached is slow to store large object, so limit the
        # number of objects here to make tests not stall.
        pairs = [((self.key_prefix + 'key%d') % i, BigObject()) for i in xrange(100)]

        def test():
            for key, value in pairs:
                set_(key, value)
                result = get_(key)
                assert result == value

        self.total_time += run_test(test, 'test_set_get_big_object (100 objects)')

        for key, value in pairs:
          self.mc.delete(key)

    def test_set_get_big_string(self):
        set_ = self.mc.set
        get_ = self.mc.get

        # libmemcached is slow to store large object, so limit the
        # number of objects here to make tests not stall.
        pairs = [((self.key_prefix + 'key%d') % i, 'x' * 10000) for i in xrange(100)]

        def test():
            for key, value in pairs:
                set_(key, value)
                result = get_(key)
                assert result == value
        self.total_time += run_test(test, 'test_set_get_big_string (100 objects)')

    def test_set_big_string(self):
        set_ = self.mc.set

        # libmemcached is slow to store large object, so limit the
        # number of objects here to make tests not stall.
        pairs = [((self.key_prefix + 'key%d') % i, 'x' * 10000) for i in xrange(100)]

        def test():
            for key, value in pairs:
                set_(key, value)
        self.total_time += run_test(test, 'test_set_big_string (100 objects)')

        for key, value in pairs:
            self.mc.delete(key)

    def test_get(self):
        pairs = zip(self.keys, self.values)
        for key, value in pairs:
            self.mc.set(key, value)

        get = self.mc.get

        def test():
            for key, value in pairs:
                result = get(key)
                assert result == value
        self.total_time += run_test(test, 'test_get')

        for key, value in pairs:
            self.mc.delete(key)

    def test_get_big_object(self):
        pairs = [((self.key_prefix + 'bkey%d') % i, BigObject('x')) for i in xrange(100)]
        for key, value in pairs:
            self.mc.set(key, value)

        get = self.mc.get
        expected_values = [BigObject('x') for i in xrange(100)]

        def test():
            for i in xrange(100):
                result = get((self.key_prefix + 'bkey%d') % i)
                assert result == expected_values[i]
        self.total_time += run_test(test, 'test_get_big_object (100 objects)')

        for key, value in pairs:
            self.mc.delete(key)

    def test_p_app_get(self):
        keys = ['Users/getUserById/1/False', '1_db:users_map', '2_db:table_group', '2_db:shard_infoN3']
        def test():
            for key in keys:
                self.mc.get(self.key_prefix + key)

        self.total_time += run_test(test, 'test_p_app_get')

    def test_get_multi(self):
        pairs = zip(self.keys, self.values)
        for key, value in pairs:
            self.mc.set(key, value)

        keys = self.keys
        expected_result = dict(pairs)

        def test():
            result = self.mc.get_multi(keys)
            assert result == expected_result
        self.total_time += run_test(test, 'test_get_multi')

        for key, value in pairs:
            self.mc.delete(key)

    def test_get_list(self):
        pairs = zip(self.keys, self.values)
        for key, value in pairs:
            self.mc.set(key, value)

        keys = self.keys
        expected_result = self.values

        def test():
            result = self.mc.get_list(keys)
            assert result == expected_result
        self.total_time += run_test(test, 'test_get_list')

        for key in self.keys:
            self.mc.delete(key)

def main(module_name, module, prefix=''):
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option('-a', '--server-address', dest='server_address',
            default='127.0.0.1:11211',
            help="address:port of memcached [default: 127.0.0.1:11211]")
    parser.add_option('-n', '--num-tests', dest='num_tests', type='int',
            default=1000,
            help="repeat counts of each test [default: 1000]")
    parser.add_option('-v', '--verbose', dest='verbose',
            action='store_true', default=False,
            help="show traceback infomation if a test fails")
    parser.add_option('-p', '--profile', dest='profile',
            action='store_true', default=False,
            help="store profiling log for every test")
    parser.add_option('-q', '--quiet', dest='quiet',
            action='store_true', default=False,
            help="don't output test results")
            
    global options
    options, args = parser.parse_args()

    print "Benchmarking %s..." % module_name
    
    if options.profile:
        import hotshot
        prof = hotshot.Profile("%s.prof" % name)
        prof.start()
        
    b = Benchmark(module, options, prefix)

    if options.profile:
        prof.stop()
        prof.close()

    print "Total_time is %f" % b.total_time
    print '---'


if __name__ == '__main__':
    # import cmemcache
    # import cmemcached
    import memcache
    import pylibmc
    import redispy
    import handlersocket
    import handlersocket_innodb

    modules = [
        # ('cmemcache', cmemcache),
        # ('cmemcached', cmemcached),
        ('memcache', memcache),
        ('pylibmc', pylibmc),
        ('redispy', redispy),
        ('handlersocket myisam', handlersocket),
        ('handlersocket innodb', handlersocket_innodb),
    ]


    for name, module in modules:
        main(name, module)