天天看點

泛型程式設計的困境

原文:

http://research.swtch.com/generic

常用的資料結構(vectors,queues,maps,trees,等等)似乎是評估一個新語言的一個熱門話題。Go語言的FAQ中有一條就是關于

Go中的泛型程式設計

。對于泛型程式設計的通常有以下三種處理方式:

1.(C語言)放棄泛型。這樣苦了程式員,但是這樣沒前增加太多複雜的東西到語言中。

2.(C++語言)編譯期特化或者大量地展開代碼。這樣苦了編譯器。編繹器生成一堆代碼,而大部分是無用的,需要一個很好的連結器去清除重複的副本。為每一個類型生成一份代碼,也許這樣會讓代碼高效,但是程式是一個整體,這樣會造成對cpu的cache不友好。我曾聽說一個簡單的庫修正和移除了模闆後,text段(即動态連結庫的檔案格式中的text段)的大小從M級降到10K。

3.(Java語言)隐式地把所有東西裝箱。這樣苦了程式,這樣執行起來會變慢。

對比C語言的手寫,C++語言的編譯器生成,Java代碼最簡單,但是最低效,無論是從時間還是空間來說。因為所有的操作都要隐式地裝箱和拆箱。一個byte的vector容器(Vector<Byte>)所占的空間比遠超一個位元組每一個byte。想要隐藏裝箱和拆箱會讓類型系統變複雜。從另一個方面來說,這個也許是指令cache友好的,因為它把一個byte的vector(Vector<Byte>)可以分開來寫每一個byt e。

泛型程式設計的困境是:要麼苦了程式員,要麼苦了編繹器,要麼降低運作時效率。

=====================================================

原文作者是Go語言的實作者之一。

從Go的FAQ中也可以看到他們并不急于去實作泛型,是因為還沒有找到一個合适的實作方案去解決上面的困境。

因為Go目前沒有泛型,是以隻能用interface來實作常用的資料結構了。但是從我個人角度來看Go中的interface的效率有點慢(比C++中的虛函數要慢,想想一個Vector容器,調用一個get函數,都比調用C++的一個虛函數還要慢。。)。

是以在Go1.0之前,有Vector容器時,另外還有一個IntVector和一個StringVector。想想有夠蛋疼的,如果我想用一個高效float的Vector,是不是還要寫一個FloatVector?

如果Go能支援泛型,那真是相當令人高興的一件事。