輸出整數型別 (Integer) 或許是我們最常需要使用的功能之一。
網路上常見的建議為:
在 C 語言,我們常用
sprintf snprintf 來操作。
在 C++ ,我們可以使用 stringstream 來轉換。
另外,也可以使用 boost 來轉換。
這三種各有優缺點,在
The String Formatters of Manor Farm 一文中針對整數轉字串做了一個完整的分析。
在這裡,我們不考慮是否會發生緩衝區溢位的問題 (sprint),也不考慮程式碼是否容易辨別 (我們都把它包成一個函式)。那,到底誰最快呢?
在 boost 網站上有
他們自己做的測試。
不過我還是喜歡自己測,眼見為憑。
我寫了一支
小程式 CastIntToStringTest.cc ,其中我將 snprintf 和 ostringstream 重新包裝成下列函式。
char *IntToPtr(int i)
{
static char buf[50];
snprintf(buf, sizeof(buf), "%d", i);
return buf;
}
string IntToString(int i)
{
ostringstream oss;
oss << i;
return oss.str();
}
我的 g++ 版本為 gcc version 4.6.2 (Debian 4.6.2-12)
OS 為 Debian sid (2012-1-22)
跑在 VirtualBox 上面
Host 為 Mac Mini Server (Core 2 Due 版),OS 為 Lion。
執行結果如下
hialan@debian:~$ ./CastIntToStringTest
Test IntToPtr: 123456
Test IntToString: 123456
Test lexical_cast: 123456
Run 10000000 times.
IntToPtr: 2 secs.
IntToString: 11 secs.
lexical_cast<string>: 4 secs.
hialan@debian:~$
在官方做的測試中,int -> string 的轉換結果為
lexical_cast : 20
std::stringstream with construction : 121
std::stringstream without construction : 21
scanf/printf : 16
我想差距不大。假設官方的測試結果是 ok 的。
不過我的測試只針對單一型別做轉換。在嚴格條件下可以針對這類案例做最佳化。
但如果是要一般化的解決方案,我想用 lexical_cast 是不錯的選擇。程式碼精簡明確,又可套用在不同型別。
而且結果比 sringstream 好上太太太多了。
至於 sprintf ? 如果想要自己處理記憶體的話,可能是個好選擇。