2013-06-12 106 views
3

我有一個奇怪的問題。據this這樣的帖子,我認爲IDLE比在命令行上運行我的代碼要慢。但是,我看到完全相反的情況。IDLE和命令行之間的性能差異。 IDLE在哪裏表現更好

程序比較兩個文件並將匹配的行匹配在一起並將所有匹配寫入新文件。我認爲它類似於SQL中的連接。但是我需要忽略沒有匹配的行。下面是該程序的功能概述:

  • 程序讀取一個大文件〜1KB並存儲密鑰值對每行的字典
  • 然後開始讀其他大型文件〜1KB。對於每一行,它都會測試字典中的密鑰是否存在於新文件中。如果是這樣,它將這些對寫入一個新文件。

它似乎像試圖訪問非常大的字典時程序卡住了。在IDLE中運行需要大約2-3分鐘,但是在1小時後程序仍然沒有在命令行上完成。當我訪問write_file時,其寫入速度非常緩慢。

這裏就是數據由製表符分隔的第一文件的一些簡化的數據和數量爲鍵和值是信息:

20 \ tinfo_first_file_20 \ n

18 \ tinfo_first_file_18 \ n

下面是該第二文件的一個例子:

20 \ tinfo_second_file_20 \ n

30 \ tinfo_second_ file_20 \ n

這裏是正在寫入的文件的例子:

20 \ tinfo_first_file_20 \ T20 \ tinfo_second_file_20 \ n

功能

def pairer(file_1, file_2, write_file): 
    wf = open(write_file, 'w') 
    f1 = open(file_1, 'r') 

    line = f1.readline() 
    d = {} 
    while line != "": 
     key, value = line.strip('\n').split('\t') 
     d[key] = value 
     line = f1.readline() 

    f2 = open(file_2, 'r') 
    line_2 = f2.readline() 

    while line_2 != "": 
     key, value = line_2.strip('\n').split('\t') 
     if key in d.keys(): 
      to_write = key +'\t' + d[key] + '\t' + key +'\t'+ value + '\n' 
      wf.write(to_write) 
     line_2 = f2.readline() 

我如何運行代碼in IDLE

if __name__=="__main__": 

    pairer('file/location/of/file_1', 'file/location/of/file_2', 'file/location/of/write_file') 

我怎麼運行終端

if __name__=="__main__": 
    parser = argparse.ArgumentParser() 
    parser.add_argument('file_1', action="store") 
    parser.add_argument('file_2', action="store") 
    parser.add_argument('write_file', action="store") 
    results = parser.parse_args() 
    pairer(results.file_1, results.file_2, results.write_file) 

代碼的所有代碼是實際代碼的簡化。我希望我能夠包含足夠的內容,讓別人指出我正確的方向,但不要太多,所以我堅持這一點。我是編程新手,所以這可能是一個顯而易見的問題,但我一直無法找到任何東西。

使用終端的字典是否有最大尺寸?它以不同的方式存儲,最終會讓我的記憶變得更大?

我有一個Mac OSX 10.8。 Tkinter已更新。我正在使用python2.7。 在此先感謝。

編輯:程序到達這一點

之前它有大約30分鐘的其他分析做。但它只是在這裏失敗。不確定這是否相關。另一部分是將每個〜30kb的大文件分成22個小文件。這裏沒有涉及字典,速度也差不多。所以我可以在較小的層面上處理數據。

編輯2:使用終端時

是否存儲器明確不同?

而且我注意到另一件事:當我看活動監視器應用程序似乎當我在空閒運行代碼以使用更多的CPU。我看起來好像使用了多個處理器,但這沒有意義。由於我的代碼沒有寫入並行運行。當我在IDLE中運行時,電腦也會產生更多噪音。不是很定量,而是一個觀察。

+2

見http://stackoverflow.com/questions/11241523/why-does-python-code-run-faster-in-a-function –

+1

@FredrikPihl +1 - 不知道,但在這種情況下,這兩個版本做大部分工作在'pairer()'函數,所以它似乎並不彷彿這將佔到差異。 – Aya

+0

@Aya - 你是正確的。真的不看看代碼:-) lokkup成員變量是死的慢順便說一句,但這並不要麼解釋它... –

回答

0

1KB的文件,聲音非常小,但這裏有可能解決這個問題的一些提示,因爲這個問題是一個有點含糊:採用argparse

意味着,在命令行你需要這樣的:

python prog.py --file_1 file --file_2 file --write_file output 

我不知道這是否是你想要的。你可能只是保持簡單,做這樣的事情:

if __name__ == '__main__': 
    file_1 = sys.argv[1] 
    file_2 = sys.argv[2] 
    write_file = sys.argv[3] 
    pairer(file_1, file_2, write_file) 

與您會調用它:

python prog.py file_1 file_2 write_file 

也,這主要是一個風格問題,但我會修改pairer一個一點點 - 在文件中使用for循環,並且不要創建keys()列表。

def pairer(file_1, file_2, write_file): 

    d = {} 
    # using 'with' prevents lost resources! 
    with open(file_1, 'r') as f1: 
     for line in f1: 
      # no arguments in strip clears all whitespace 
      key, value = line.strip().split('\t') 
      d[key] = value 

    f2 = open(file_2, 'r') 
    line_2 = f2.readline() 
    with open(file_2, 'r') as f2, open(write_file, 'w') as wf: 
     key, value = line_2.strip().split('\t') 
     # don't do 'if key in d.keys()' because .keys() constructs a list of keys 
     # the in operator checks the key directly, which is O(1) instead of O(n) 
     # this should give you a pretty big speed boost 
     if key in d: 
      # this is probably a trivial speed difference, but you could try it this way: 
      to_write = '\t'.join([key, d[key], key, value + '\n']) 
      wf.write(to_write)