And we should watch out for things like this:
The MySQL version:
bitmap_is_subset(x, y)
The C++ "way":
(x & y) == x
It looks cute, but how is it implemented!?
The thing is, there are simply great ways to optimize this operation
if you write custom code to do it.
Another problem I see is that the bitmap implementation basically
encourages sub-optimal code. Take a look at the Drizzle implementation
of ha_get_max_bit() (a function I use in PBXT) below. The Drizzle
version is maybe 100 times more understandable, but I would guess the
MySQL version is at least 10 times faster!
In general the thing that makes me suspicious of the C++ standard lib
is that it is not necessarily written to be "database server
grade" (especially if they put the emphasis on readability instead of
speed).
By "database server grade" I mean _every_ instruction counts.
---------------------------------------------------------------
static u_int ha_get_max_bit(MX_BITMAP *map)
{
#ifdef DRIZZLED
size_t i;
if (!map->any())
return 0;
for (i=0; i<map->size(); i++) {
if (map->test(i))
break;
}
return i+1;
#else
my_bitmap_map *data_ptr = map->bitmap;
my_bitmap_map *end_ptr = map->last_word_ptr;
my_bitmap_map b;
u_int cnt = map->n_bits;
for (; end_ptr >= data_ptr; end_ptr--) {
if ((b = *end_ptr)) {
my_bitmap_map mask;
if (end_ptr == map->last_word_ptr &&
map->last_word_mask)
mask = map->last_word_mask >> 1;
else
mask = 0x80000000;
while (!(b & mask)) {
b = b << 1;
/* Should not happen, but if it does, we hang!
*/
if (!b)
return map->n_bits;
cnt--;
}
return cnt;
}
if (end_ptr == map->last_word_ptr)
cnt = ((cnt-1) / 32) * 32;
else
cnt -= 32;
}
return 0;
#endif
}
On May 6, 2009, at 9:03 AM, Stewart Smith wrote:
So, there was a perf regression noticed as a result of replacing
my_bitmap with std::bitset.
This is why:
These code changes:
- MY_BITMAP *save_read_set, *save_write_set;
+ bitset<MAX_FIELDS> *save_read_set, *save_write_set;
means we stop doing things like this:
- bitmap_init(&column_bitmap, bitmap, head->s->fields, false);
and instead statically say "this bitset has MAX_FIELDS bits".
For the bitmap_init() call, the my_bitmap code only allocates enough
buffer space for the number of fields (in this case, grabbing the
field
count from the table share).
For the std::bitset, this allocates room for MAX_FIELDS, which is
4096.
i.e. a full 512 byte bitmap.
So for tables with around 4000 columns, both implementations are
likely
close in performance :)
However, for the common case (e.g. sysbench), it isn't. I prove with
benchmarks (same code, just changing MAX_FIELDS down to 64) and not
handwaving:
$ uname -a
Linux willster 2.6.30-020630rc2-generic #020630rc2 SMP Wed Apr 15
13:20:18 UTC 2009 x86_64 GNU/Linux
$ grep 'model name' /proc/cpuinfo
model name : Intel(R) Core(TM)2 Duo CPU T7250 @ 2.00GHz
model name : Intel(R) Core(TM)2 Duo CPU T7250 @ 2.00GHz
$ sysbench --test=oltp --drizzle-host=127.0.0.1 --drizzle-port=9306
--drizzle-db=test --drizzle-mysql=off --drizzle-user=root
--db-ps-mode=disable --db-driver=drizzle --drizzle-table-engine=myisam
--max-time=60 --max-requests=2000 --oltp-read-only=on
--oltp-table-size=20000 --num-threads=8 run
MAX_FIELDS=4096 with std::bitset
read/write requests: 28000 (3016.51 per sec.)
read/write requests: 28000 (2804.91 per sec.)
read/write requests: 28000 (2824.13 per sec.)
read/write requests: 28000 (2830.43 per sec.)
MAX_FIELDS=64 with std::bitset
read/write requests: 28000 (3274.91 per sec.)
read/write requests: 28000 (2981.82 per sec.)
read/write requests: 28000 (2921.28 per sec.)
read/write requests: 28000 (2934.67 per sec.)
read/write requests: 28000 (3295.95 per sec.)
http://gcc.gnu.org/onlinedocs/libstdc++/manual/bitset.html
Is a good read - especially the completely useless suggestions for
workarounds. "just burn megabytes of memory", or "limit what your
program can accept" or (my favourite) "just use the compiler and
linker
at runtime". Some redeption with theorising that the last solution is
that of a "raving lunatic".
The problem is that vector<bool> doesn't behave like a normal vector
anymore. There have been recent journal articles which discuss the
problems (the ones by Herb Sutter in the May and July/August 1999
issues
of C++ Report cover it well). Future revisions of the ISO C++
Standard
will change the requirement for vector<bool> specialization. In the
meantime, deque<bool> is recommended (although its behavior is sane,
you probably will not get the space savings, but the allocation
scheme
is different than that of vector).
So it's going to be vector<bool> to the rescue.
I then want to bench it against Mats Kindal's magic code.
--
Stewart Smith
_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help : https://help.launchpad.net/ListHelp
--
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreaming.org
pbxt.blogspot.com
_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help : https://help.launchpad.net/ListHelp