标签:blog io ar 使用 for sp 数据 on 2014
最近在阅读一个开源的C++代码,里面用到了大量的STL里面的东西。也许是自己一直用C而很少用C++来实现算法的原因,STL里面大量的模板令人心烦。一直对STL的效率表示怀疑,但在网上搜到这样一个帖子,说C的标准库里面快速排序比STL的标准排序要慢!于是,便认真的看了下二者的源码。其实两个使用的算法是完全类似的,而C标准库里面的qsort之所以比std::sort慢,是因为C语言中为了适配所有的数据结构使用了空指针。下面以更为简单的插入排序为例说明这个问题。
插入排序的算法实现代码:
void insert_sort(int a[], int n) { int i, j; int t; for (i = 1; i < n; i++) { t = a[i]; j = i; while ((j > 0) && (a[j - 1] > t)) { a[j] = a[j - 1]; j--; } a[j] = t; } }
通用数据类型的插入排序实现代码:
void general_insert_sort(void* arr, int num_element, int element_bytes, int (*cmp_fun)(void* p1, void* p2)) { int i, j; int t[1024]; if (element_bytes > 4096){ return; } #define ELE(arr, i) (void*)(((unsigned)arr) + (i) * element_bytes) for (i = 1; i < num_element; i++) { memcpy(t, ELE(arr, i), element_bytes); j = i; while ((j > 0) && (cmp_fun(ELE(arr, j - 1), (void*)t))) { memcpy(ELE(arr, j), ELE(arr, j - 1), element_bytes); j--; } memcpy(ELE(arr, j), (void*)t, element_bytes); } }
上面的方法虽然解决了任意数据类型的问题,但是其效率并不怎么高。相对于上述第一段代码而言,简单的赋值语句必须得调用一个函数来拷贝数据,简单的比较语句,则需要调用外部传入一个函数指针得到比较结果。这是效率低下的根本原因。
而C++模板参数的出现,只需要写一份代码,编译器根据你调用时候的数据类型自动生成新的代码。其实用宏也可以完成通用的功能。这里给出C语言宏的代码,C++模板的代码也很简单。
#define FIV_IMPLEMENT_INSETT_SORT(function_name, T, LT_CMP)void function_name(T* arr, int low, int high){ int i, j; T t; for (i = low + 1; i < high; i++) { t = arr[i]; j = i; while ((j > low) && (LT_CMP(t, arr[j - 1]))) { arr[j] = arr[j - 1]; j--; } arr[j] = t; }}
#define CMP(a, b) ((a) < (b))
FIV_IMPLEMENT_INSETT_SORT(insert_sort_int, int, CMP)
这样就有一个用于整数排序的函数insert_sort_int可用,如果是你自定义的结构体类型,则同样只需要写这两个宏就可以了。
结尾:
用C++模板产生的代码大小是不使用模板的很多倍,而用C语言的空指针可以支持任意数据类型,代码大小很小,而用C语言的宏定义产生模板函数的代码大小理论上和使用STL的大小是一样的。
标签:blog io ar 使用 for sp 数据 on 2014
原文地址:http://blog.csdn.net/celerychen2009/article/details/40655239