程序庫的設(shè)計(jì)就是一個折衷的過程。理想的程序庫應(yīng)該是短小的、快速的、強(qiáng)大的、靈活的、可擴(kuò)展的、直觀的、普遍適用的、具有良好的支持、沒有使用約束、沒有錯誤的。這也是不存在的。為尺寸和速度而進(jìn)行優(yōu)化的程序庫一般不能被移植。具有大量功能的的程序庫不會具有直觀性。沒有錯誤的程序庫在使用范圍上會有限制。真實(shí)的世界里,你不能擁有每一件東西,總得有付出。
不同的設(shè)計(jì)者給這些條件賦予了不同的優(yōu)先級。他們從而在設(shè)計(jì)中犧牲了不同的東西。因此一般兩個提供相同功能的程序庫卻有著完全不同的性能特征。
例如,考慮iostream和stdio程序庫,對于C++程序員來說兩者都是可以使用的。iostream程序庫與C中的stdio相比有幾個優(yōu)點(diǎn)(參見Effective C++)。例如它是類型安全的(type-safe),它是可擴(kuò)展的。然而在效率方面,iostream程序庫總是不如stdio,因?yàn)閟tdio產(chǎn)生的執(zhí)行文件與iostream產(chǎn)生的執(zhí)行文件相比尺寸小而且執(zhí)行速度快。
首先考慮執(zhí)行速度的問題。要想掌握iostream和stdio之間的性能差別,一種方法就是用這兩個程序庫來運(yùn)行benchmark程序。不過你必須記住benchmark也會撒謊。不僅很難拿出一組能夠代表程序或程序庫典型用法的數(shù)據(jù),而且就算拿出來也是沒用,除非有可靠的方法判斷出你或你的客戶的具有什么樣的特征。不過在解決一個問題的不用方法的比較上,benchmark還是能夠提供一些信息,所以盡管完全依靠benchmark是愚蠢的,但是忽略它們也是愚蠢的。
讓我們測試一個簡單的benchmark程序,只測試最基本的I/O功能。這個程序從標(biāo)準(zhǔn)輸入讀取30000個浮點(diǎn)數(shù),然后把它們以固定的格式寫到標(biāo)準(zhǔn)輸出里。編譯時(shí)預(yù)處理符號STDIO決定是使用stdio還是iostream。如果定義了這個符號,就是用stdio,否則就使用iostream程序庫。
#ifdef STDIO
#include
#else
#include
#include
using namespace std;
#endif
const int VALUES = 30000; // # of values to read/write
int main()
{
double d;
for (int n = 1; n <= VALUES; ++n) {
#ifdef STDIO
scanf("%lf", &d);
printf("%10.5f", d);
#else
cin >> d;
cout << setw(10) // 設(shè)定field寬度
<< setprecision(5) // 設(shè)置小數(shù)位置
<< setiosflags(ios::showpoint) // keep trailing 0s
<< setiosflags(ios::fixed) // 使用這些設(shè)置
<< d;
#endif
if (n % 5 == 0) {
#ifdef STDIO
printf("\n");
#else
cout << '\n';
#endif
}
}
return 0;
}
不同的設(shè)計(jì)者給這些條件賦予了不同的優(yōu)先級。他們從而在設(shè)計(jì)中犧牲了不同的東西。因此一般兩個提供相同功能的程序庫卻有著完全不同的性能特征。
例如,考慮iostream和stdio程序庫,對于C++程序員來說兩者都是可以使用的。iostream程序庫與C中的stdio相比有幾個優(yōu)點(diǎn)(參見Effective C++)。例如它是類型安全的(type-safe),它是可擴(kuò)展的。然而在效率方面,iostream程序庫總是不如stdio,因?yàn)閟tdio產(chǎn)生的執(zhí)行文件與iostream產(chǎn)生的執(zhí)行文件相比尺寸小而且執(zhí)行速度快。
首先考慮執(zhí)行速度的問題。要想掌握iostream和stdio之間的性能差別,一種方法就是用這兩個程序庫來運(yùn)行benchmark程序。不過你必須記住benchmark也會撒謊。不僅很難拿出一組能夠代表程序或程序庫典型用法的數(shù)據(jù),而且就算拿出來也是沒用,除非有可靠的方法判斷出你或你的客戶的具有什么樣的特征。不過在解決一個問題的不用方法的比較上,benchmark還是能夠提供一些信息,所以盡管完全依靠benchmark是愚蠢的,但是忽略它們也是愚蠢的。
讓我們測試一個簡單的benchmark程序,只測試最基本的I/O功能。這個程序從標(biāo)準(zhǔn)輸入讀取30000個浮點(diǎn)數(shù),然后把它們以固定的格式寫到標(biāo)準(zhǔn)輸出里。編譯時(shí)預(yù)處理符號STDIO決定是使用stdio還是iostream。如果定義了這個符號,就是用stdio,否則就使用iostream程序庫。
#ifdef STDIO
#include
#else
#include
#include
using namespace std;
#endif
const int VALUES = 30000; // # of values to read/write
int main()
{
double d;
for (int n = 1; n <= VALUES; ++n) {
#ifdef STDIO
scanf("%lf", &d);
printf("%10.5f", d);
#else
cin >> d;
cout << setw(10) // 設(shè)定field寬度
<< setprecision(5) // 設(shè)置小數(shù)位置
<< setiosflags(ios::showpoint) // keep trailing 0s
<< setiosflags(ios::fixed) // 使用這些設(shè)置
<< d;
#endif
if (n % 5 == 0) {
#ifdef STDIO
printf("\n");
#else
cout << '\n';
#endif
}
}
return 0;
}