2012-04-29 62 views
0

我問這個問題,因爲當一個循環用重複的打印語句調試時,它會減慢我原本預期的程序。我已經習慣了這一點,但現在我很好奇,爲什麼會出現這種情況的技術原因?在我看來,變量的各種計算和分配將比輸出字符串更昂貴。Python打印語句涉及多少條計算機指令?

+6

該問題與CPU指令無關;你的終端比CPU慢得多。 – geoffspear 2012-04-29 13:06:44

+0

謝謝大家的好的答案。我自學成才,我的教育才剛剛開始。 – talloaktrees 2012-04-29 14:59:28

回答

6

相當多的,但另一個重要的(甚至是最重要的)瓶頸與CPU無關:I/O開銷。一旦字節碼指令被分派並且所有參數都被轉換爲字符串,就會調用一個函數將這些字符串寫入sys.stdout。根據您的系統,以及如何運行該程序,這可能是:

  1. 從終端仿真器上磁盤
  2. 管道內的文件
  3. ,捕捉輸出一些Python對象(這就是閒置呢IIRC)完成對它的瞭解(捕獲它,將其放入GUI等)。

在案例#1中涉及磁盤I/O,這比寫入RAM容易一個數量級。與現在的CPU相比,RAM已經非常慢了。正如評論中指出的那樣,由於操作系統和Python的大量緩衝,這不是一個問題,但是仍然需要時間來發布寫入和(取決於我不太瞭解的實現細節),它可能仍然需要一些時間是否有人過早地衝洗任何緩衝區。

在情況#2,一切都保留在內存中,但它仍然是一個系統調用,一些拷貝,而另一端已讀它,並用它做什麼讓你看到(如呈現在一個奇特的終端模擬器帶有反鋸齒字體,這本身就是一項複雜的任務)。因爲它可能會同時發生,所以不會造成問題,但它仍然會給CPU帶來負擔。

如果情況#3,所有投注都關閉。它可以用bcrypt對輸出進行散列,並將它發送給我們所知的所有月球。你碰巧使用IDLE?我記得有一個投訴,IDLE是(是?)緩慢重定向輸出,特別是有很多尖齒。它必須捕獲輸出,並將其與輸出連接在一起,然後讓Tkinter進行渲染。

1

這不是CPU指令的問題,至少不是你的Python程序中的CPU指令。當您使用終端仿真程序(命令窗口)作爲輸出執行print時,要打印的字符串將被複制到內核緩衝區中,然後複製到終端進程的內存中。開銷是在上下文切換(兩個進程正在進行系統調用,即跳入內核模式)以及將字符串複製到內存中。

+0

實際上,通常IO上盤容易感到更快,因爲,除非你'sync'所有的時間/輸出數據噸,它在很大程度上緩衝,而你的程序是做其他的東西的OS可以採取刷新緩衝區的護理。另一方面,控制檯上的IO不能具有最輕的緩衝,否則用戶將不會及時看到程序打印的內容。 – 2012-04-29 13:16:50

+0

@MatteoItalia:你是對的,我忘了終端通常是線路緩衝。刪除了有關磁盤的位,以免混淆OP。 – 2012-04-29 13:19:00

2

一個巨大的,巨大的,巨大數量,尤其是如果所述輸出在屏幕上可見的,如在現代多任務系統上的終端仿真窗口。首先,如果你輸出十進制數字,每個數字都有一個divmod,相對於比較而言,這是一個相對昂貴的操作。 (如果以十六進制輸出,它可能會便宜一點,因爲每個數字只能使用移位和屏蔽來提取。)如果輸出浮點數,則需要進行更多計算;與日期和時間,有幾個月的各種長度,閏年,閏秒,DST和時區都需要考慮。

但這都只是計算和邏輯,所以它是由什麼來了矮。

接着Python有將輸出發送文本到終端用於顯示,這意味着該操作系統必須在步驟通過緩衝來傳輸數據,則喚醒其他過程。終端進程掃描其控制序列的輸入以移動光標或更改顏色。然後,文本渲染器會掃描文本中需要特殊處理的字符:可能會應用一些合成重音符號,或者需要重新排列用於顯示的一些從右到左的腳本。

一旦文本被擺出來,終端告訴它需要重繪它的窗口區域的窗口管理器和窗口管理器檢查它是否是可見的 - 這可能是最小化或隱藏在其它窗口後面。終端會被告知哪個區域實際上需要繪畫,最後用適當的字體和顏色繪製文字和字體的抗鋸齒。窗戶是否有一個酷炫的透明背景?這也必須合併。

根據不同的視窗系統上,像素然後可以去另一行通過操作系統緩衝區來一個合成器,這實際上繪製窗口內容到屏幕上,同時考慮到窗口的透明度。

最後,像素到屏幕上,他們幾乎都被數以百萬計的繼任者被一掃之前看到的時候,當你看到輸出流過去過於快速閱讀。

這是驚人的,我們的電腦爲我們做了多少工作要做。