/* * balloc.C: Test and time the block allocator * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are documented in doc/poddoc/license.pod * * $Id: balloc.C,v 1.3 2007/09/05 11:23:15 pippijn Exp $ */ #include "unit/test.h" #ifndef TIMING #define TIMING 0 #endif #ifndef SHOWSIZE #define SHOWSIZE 0 #endif /** * Enabling TIMING will benchmark the block allocator against system malloc (). * Enabling SHOWSIZE will show you the compiler's idea of each structure's size. */ struct myuser_balloc : object, balloc, has_metadata { typedef indexing_vector login_vector; typedef indexing_vector memo_vector; typedef unordered_vector mzignore_vector; // memo ignores myuser_balloc () : has_metadata (metadata::MYUSER) { } char name[NICKLEN]; char pass[NICKLEN]; char email[EMAILLEN]; login_vector logins; /* user_t's currently logged in to this */ time_t registered; time_t lastlogin; list_t chanacs; soper_t *soper; unsigned int flags; memo_vector memos; /* store memos */ unsigned int memoct_new; unsigned int memo_ratelimit_num; /* memos sent recently */ time_t memo_ratelimit_time; /* last time a memo was sent */ mzignore_vector memo_ignores; /* openservices patch */ list_t access_list; list_t nicks; /* registered nicks, must include mu->name if nonempty */ list_t subscriptions; /* presence subscriptors */ protected: void _destroy () { delete this; } }; struct myuser_noballoc : object, has_metadata { typedef indexing_vector login_vector; typedef indexing_vector memo_vector; typedef unordered_vector mzignore_vector; // memo ignores myuser_noballoc () : has_metadata (metadata::MYUSER) { } char name[NICKLEN]; char pass[NICKLEN]; char email[EMAILLEN]; login_vector logins; /* user_t's currently logged in to this */ time_t registered; time_t lastlogin; list_t chanacs; soper_t *soper; unsigned int flags; memo_vector memos; /* store memos */ unsigned int memoct_new; unsigned int memo_ratelimit_num; /* memos sent recently */ time_t memo_ratelimit_time; /* last time a memo was sent */ mzignore_vector memo_ignores; /* openservices patch */ list_t access_list; list_t nicks; /* registered nicks, must include mu->name if nonempty */ list_t subscriptions; /* presence subscriptors */ protected: void _destroy () { delete this; } }; struct hugestruct : balloc { char buf[20000]; char otherbuf[20000]; char hugebuf[20000]; }; struct hugestruct_noballoc { char buf[20000]; char otherbuf[20000]; char hugebuf[20000]; }; struct tinystruct : balloc { char onebyte; }; struct tinystruct_noballoc { char onebyte; }; // not inline because otherwise the compiler might optimise the loop away static hugestruct * create () { return new hugestruct; } #if TIMING static hugestruct_noballoc * create_noballoc () { return new hugestruct_noballoc; } static tinystruct * create_tinystruct () { return new tinystruct; } static tinystruct_noballoc * create_tinystruct_noballoc () { return new tinystruct_noballoc; } static myuser_balloc * create_myuser_balloc () { return new myuser_balloc; } static myuser_noballoc * create_myuser_noballoc () { return new myuser_noballoc; } #endif test<1> () { hugestruct *v[3000]; #if TIMING hugestruct_noballoc *n[3000]; tinystruct *t[3000]; tinystruct_noballoc *tn[3000]; myuser_balloc *mub[3000]; myuser_noballoc *munb[3000]; int i = 1000; #if SHOWSIZE std::cout << "sizeof (hugestruct) == " << sizeof (hugestruct) << " (~60KB)\n"; std::cout << "sizeof (hugestruct_noballoc) == " << sizeof (hugestruct_noballoc) << " (~60KB)\n"; std::cout << "sizeof (tinystruct) == " << sizeof (tinystruct) << " (~16B)\n"; std::cout << "sizeof (tinystruct_noballoc) == " << sizeof (tinystruct_noballoc) << " (~1B)\n"; std::cout << "sizeof (myuser_balloc) == " << sizeof (myuser_balloc) << " (~500B)\n"; std::cout << "sizeof (myuser_noballoc) == " << sizeof (myuser_noballoc) << " (~500B)\n"; #endif double start = now (); while (--i) { #endif for (int j = 0; j < 3000; j++) v[j] = create (); for (int j = 0; j < 3000; j++) delete v[j]; #if TIMING } double end = now (); std::cout << end - start << " seconds (huge struct balloc)\n"; i = 1000; start = now (); while (--i) { for (int j = 0; j < 3000; j++) n[j] = create_noballoc (); for (int j = 0; j < 3000; j++) delete n[j]; } end = now (); std::cout << end - start << " seconds (huge struct system malloc)\n"; i = 1000; start = now (); while (--i) { for (int j = 0; j < 3000; j++) t[j] = create_tinystruct (); for (int j = 0; j < 3000; j++) delete t[j]; } end = now (); std::cout << end - start << " seconds (tiny struct balloc)\n"; i = 1000; start = now (); while (--i) { for (int j = 0; j < 3000; j++) tn[j] = create_tinystruct_noballoc (); for (int j = 0; j < 3000; j++) delete tn[j]; } end = now (); std::cout << end - start << " seconds (tiny struct system malloc)\n"; i = 1000; start = now (); while (--i) { for (int j = 0; j < 3000; j++) mub[j] = create_myuser_balloc (); for (int j = 0; j < 3000; j++) delete mub[j]; } end = now (); std::cout << end - start << " seconds (myuser balloc)\n"; i = 1000; start = now (); while (--i) { for (int j = 0; j < 3000; j++) munb[j] = create_myuser_noballoc (); for (int j = 0; j < 3000; j++) delete munb[j]; } end = now (); std::cout << end - start << " seconds (myuser system malloc)\n"; #endif hugestruct::finalise (); tinystruct::finalise (); myuser_balloc::finalise (); } #include "unit/runtest.h"