我写了两个简单的程序来比较 g_slice_alloc()和 g_malloc()的速度。
g_slice_alloc()版本:
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
gchar *mem[1000000];
gint i;
for(i=0;i<1000000;i++){
mem[i]=g_slice_alloc(50);
}
for(i=0;i<1000000;i++){
g_slice_free1(50,mem[i]);
}
return 0;
}
和 g_malloc()版本
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
gchar *mem[1000000];
gint i;
for(i=0;i<1000000;i++){
mem[i]=g_malloc(50);
}
for(i=0;i<1000000;i++){
g_free(mem[i]);
}
return 0;
}
编译它们
gcc slice.c -o slice `pkg-config --libs --cflags gtk+-3.0`
gcc malloc.c -o malloc `pkg-config --libs --cflags gtk+-3.0`
并测试它们
$ time ./slice
real 0m0.091s
user 0m0.063s
sys 0m0.025s
$ time ./malloc
real 0m0.071s
user 0m0.050s
sys 0m0.021s
g_slice_alloc()版本预计运行得更快,但实际上并非如此。为什么它更慢?
这是一个很好的测试案例吗?
我尝试了另一种测试速度的方法。
#include <gtk/gtk.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
gchar *mem[1000000];
gint i;
for(i=0;i<1000000;i++){
gint j=i>10000?10000:i;
mem[i]=g_slice_alloc(j);
}
for(i=0;i<1000000;i++){
gint j=i>10000?10000:i;
g_slice_free1(j,mem[i]);
}
return 0;
}
#include <gtk/gtk.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
gchar *mem[1000000];
gint i;
for(i=0;i<1000000;i++){
gint j=i>10000?10000:i;
mem[i]=g_malloc(j);
}
for(i=0;i<1000000;i++){
gint j=i>10000?10000:i;
g_free(mem[i]);
}
return 0;
}
这次他们非常接近,有时 g_slice_alloc()更快,而somtime g_malloc()更快。
$ time ./malloc
real 0m1.515s
user 0m0.285s
sys 0m1.229s
$ time ./slice
real 0m1.521s
user 0m0.278s
sys 0m1.215s
但是这个测试不能证明 g_slice_alloc()更快,它只是告诉 g_slice_alloc()与 g_malloc()
答案 0 :(得分:4)
glibc
以来, GSlice
的malloc已经改进了很多(当glibc的malloc非常慢时)。 GSlice曾经比malloc快得多,但是由于malloc中的积极优化,现在它更快,特别是对于线程较多的应用程序。与此同时,GSlice
自添加以来并没有真正发生重大变化。
AFAIK,现在使用GSlice
的唯一真正原因是它在不同平台上更加稳定(例如,显然Windows'momooc对于GStreamer来说太慢了。)
所有这一切,你所拥有的并不是一个好的考验。像GSlice
这样的slab风格的分配器传统上擅长的是减少内存碎片,这是由大量不同大小的分配/释放混合在一起造成的。你拥有的是一堆分配,随后是一堆免费。
此外,像GSlice
这样的分配器依赖于相同大小的分配,因此增加分配大小的测试部分不能很好地工作 - GSlice
用于对象,而不是字符串和缓冲区。