Tags: c
fdatasync() makes db4o 10-20% faster
By MD on Mar 3, 2008 | In db4o | Send feedback »
I have investigated how much fdatasync() makes db4o faster on Linux. It showed 10-20% faster performance in commit.
This benchmarking was done on Linux2.6, write cache off, ext3 file system, with db4o 6.4.
fdatasync() adapter
---------- 3: insert ----------
Used Memory: 273600/5177344
total commit cost: 33816 ms
average commit cost: 135 ms
Execution Time: 36625ms
Used Memory: 530904/5177344
---------- END -------------------- 9: update ----------
Used Memory: 289840/5177344
total commit cost: 38886 ms
average commit cost: 155 ms
Execution Time: 45488ms
Used Memory: 348824/5177344
---------- END -------------------- 11: delete ----------
Used Memory: 349088/5177344
total commit cost: 49090 ms
average commit cost: 196 ms
Execution Time: 52867ms
Used Memory: 576280/5177344
---------- END ----------fsync adapter(the default one on Java)
---------- 3: insert ----------
Used Memory: 354584/5177344
total commit cost: 38190 ms
average commit cost: 152 ms
Execution Time: 41294ms
Used Memory: 659360/5177344
---------- END -------------------- 9: update ----------
Used Memory: 372136/5177344
total commit cost: 45015 ms
average commit cost: 180 ms
Execution Time: 50755ms
Used Memory: 428448/5177344
---------- END -------------------- 11: delete ----------
Used Memory: 428712/5177344
total commit cost: 49602 ms
average commit cost: 198 ms
Execution Time: 52775ms
Used Memory: 651192/5177344
---------- END ----------
The performance improvements depend on, how frequently user data is committed, and the implementation of fdatasync call. But even in the worst case, it is as fast as the default one.
BTW, fdatasync have triggered an inconsistent state in fread&fwrite. As people suggest, I should have avoided to mix POSIX(direct) and Standard C(buffered).
"Interface" in C
By MD on Feb 27, 2008 | In Ease Of Use | Send feedback »
Recently, I began to study C programming language. I used to be a Java guy, but have felt like doing that to contribute to any serious device projects here in Japan.
Java is new, object oriented language. But C is old, not object oriented.
What made me surprised was that I couldn't find a way to cut a dependency. I can define a template, but they are exposed in terms of "coupling" object oriented concept.
Before diving into C world, to avoid such a "spagetti", I would like to get a gut feeling about dependency management.
Then, I have investigated Linux VFS(Virtual File System) design. A file system in Linux is well abstracted, so must have a good design in C.
"The VFS is object-oriented. A family of data structures represents the common file model. There data structures are akin to objects. Because the kernel is programmed strictly in C, without the benefit of a language directly supporting object-oriented paradigms, the data structures are represented as C structures. The structures contain both data and pointers to filesystem-implemented functions that operate on the data." - page212, Linux Kernel Development Second Edition, Robert Love
Ah-ha, a strucrue could be used like an interface... OK, let's nail down the source. Here's a code snippet from linux/fs.c.
struct super_block {
...
struct super_operations *s_op;
...
};
Methods look defined as an interface. So what about super_operations?
struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *);
void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
void (*write_super_lockfs) (struct super_block *);
void (*unlockfs) (struct super_block *);
int (*statfs) (struct super_block *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);...
};
Mmmm, something looks strange. I wonder why they have an argument of its body, "struct super_block *" or "struct inode *".
Yes, because there is no such a thing like "instance" in C. So you can not access to an instance inside a method body, like "this" in Java. This is a bit strange, but still OK.
Yet wait, passing itself to methods mean that an interface(operations struct) depends on its concrete type! That's too bad... Its implementation can be abstracted, but not like an interface to cut dependencies.
How can I put an abstraction with an interface to cut dependencies?
I found a way to do that with a generic pointer. I am trying to test "List" interface Java design in C. Performance may matter, but still look promissing. Let's see...