2016-07-24 23 views
5

我打算經常從許多不同的文件中讀取/寫入小塊信息。以下有些人爲的例子顯示,使用os操作直接操作文件描述符所花費的時間大大縮短。除了文件對象的便利性之外,我是否還有缺點?可以使用os.open/read/write/close嗎?

import os 
import time 

N = 10000 
PATH = "/tmp/foo.test" 

def testOpen(): 
    for i in range(N): 
     with open(PATH, "wb") as fh: 
      fh.write("A") 

    for i in range(N): 
     with open(PATH, "rb") as fh: 
      s = fh.read() 

def testOsOpen(): 
    for i in range(N): 
     fd = os.open(PATH, os.O_CREAT | os.O_WRONLY) 
     try: 
      os.write(fd, "A") 
     finally: 
      os.close(fd) 

    for i in range(N): 
     fd = os.open(PATH, os.O_RDONLY) 
     try: 
      s = os.read(fd, 1) 
     finally: 
      os.close(fd) 

if __name__ == "__main__": 
    for fn in testOpen, testOsOpen: 
     start = time.time() 
     fn() 
     print fn.func_name, "took", time.time() - start 

採樣運行:

$ python bench.py 
testOpen took 1.82302999496 
testOsOpen took 0.436559915543 
+0

什麼版本的python? – user2682863

+0

@ user2682863,它必須是Python 2 - 在Python 3中,低級IO操作需要並返回「像字節的對象」而不是字符串。也就是說,這段代碼不會在Py3下運行。 –

+0

我正在使用2,但很好奇,如果有3值得注意的差異。 – Ben

回答

1

我來回答剛纔所以本文不停留開放永遠;-)

這確實有點說:因爲你已經注意到,一個file對象更方便。在一些情況下,它也更加功能;例如,它有自己的緩衝層來加速面向行的文本操作(如file_object.readline())(順便說一句,這也是速度較慢的原因之一)。而且,對象致力於在所有平臺上以相同的方式工作。

但是,如果您不需要/需要這樣做,那麼使用低級別文件描述符函數就沒有什麼不對。後者有很多,並非所有平臺都支持,並且並非所有平臺都支持所有選項。當然,您有責任將自己限制在您所關心的平臺的交集中的操作子集(這通常適用於os中的所有函數,而不僅僅是其文件描述符函數 - 名稱os是一個強有力的提示它包含的東西可能取決於操作系統)。

關於Pythons 2和3,差異是由於Python 3在所有平臺上的「文本」和「二進制」模式之間的強烈區別。這是一個Unicode世界,如果沒有指定預期的編碼,對象file的「文本模式」是沒有意義的。在Python 3中,如果文件以「文本模式」打開,則對象讀取方法返回str對象(Unicode字符串),但如果處於「二進制模式」,則返回對象bytes。類似的寫入方法。

因爲os文件描述符方法沒有編碼的概念,他們只能在Python 3(字節狀物體工作不管,例如,在Windows上,該文件描述了與低級別打開os.open()O_BINARYO_TEXT標誌)。

在實踐中,在你給的例子,這只是意味着你將不得不改變

"A" 

實例

b"A" 

請注意,您還可以使用b"..."文字語法在最新版本的Python 2,雖然它仍然只是Python 2中的字符串文字。在Python 3中,它表示一種不同類型的對象(bytes),並且文件描述符函數僅限於編寫和返回類似字節的對象。

但是,如果您使用的是「二進制數據」,那完全沒有限制。如果你使用「文本數據」,它可能可能(沒有足夠的信息來猜測你的具體情況)。

+0

謝謝,蒂姆。我很欣賞那些長期與Python密切合作的人的見解。我正在用''struct''處理二進制數據。我只是尋找一種簡單的方式來儘可能快地存儲和檢索整數,而第一類「文件」對象的性能損失看起來相當高,對我的用例沒有任何好處。雖然我開始認爲如果我關心性能,我應該只使用C. – Ben

+0

更重要的速度是,_longer_我堅持純Python ;-)只是部分地在那裏開玩笑:Python可以如此緩慢以至於不能堅持到Python迫使我想出_fundamentally_更​​好的方法。例如,也許你真正需要的是一個數據庫,或者巧妙地使用字典,或者......在表面上,打開和關閉文件只是爲了改變幾個字節而沒有任何意義:不管語言如何,完成一些小工作的高額開銷。如果你堅持使用Python,嘗試其他方法會變得更容易:-) –