[I/O 優化] PYTHON 篇


[I/O 優化] C++ 篇

「$PYTHON$」的執行速度相對於其它程式語言慢,
原因其實有很多,
其實有許多方法去優化 $PYHON$ 的執行速度,
以下介紹幾種基本的 $I/O$ 優化方法。


< $Input \ Optimize$ >
讀入的方法使用 $sys$ 模組的 $stdin$,
有以下幾種方法。

1. 一次讀一行:
from sys import stdin
line = stdin.readline()
一次讀取 $stdin$ 檔一行,
如果讀到 $EOF$ 則回傳空字串。
而讀的這一行會把前後不可見字元(包含 '\n'、' ' …等)也讀進去,
如果該行有多餘的空白,
可能會導致預期外的結果,
因此在使用時常會搭配 $strip()$ 使用,
$strip()$ 可以移除前後不可見字元。
from sys import stdin
line = stdin.readline().strip()
這樣的讀取方法,相當於 $input()$,
然而速度是相對較快的(約可以快 $20\%$ ~ $30\%$)!

2. 一次讀完 $stdin$ 檔:
from sys import stdin
lines = stdin.readlines()
這會把 $stdin$ 檔一次讀完,
並且回傳一個 $list$,
每一行讀取內容為 $list$ 的一個元素,
因此 $len(list)$ 就會是 $stdin$ 檔的總行數。
這種方法有好有壞,
好處是方便查看 $stdin$ 檔總共有幾行,
而壞處是會使用大量的記憶體去儲存資料。

3. 一次讀固定數量:
  • $read()$ 沒有參數:
from sys import stdin
chars = stdin.read()
就是把 stdin 檔一次讀完, 並回傳一個字串, 為讀取的所有內容。
  • $read()$ 有參數:
from sys import stdin
chars = stdin.read(100)
從 $stdin$ 檔一次讀 $100$ 個字元, 如果欲讀取字元總數大於 $stdin$ 檔剩餘可讀去字元數, 則讀到 $EOF$ 停止。 同樣地會回傳一個字串, 為讀取的所有內容。

4. 特別用法:
from sys import stdin
for line in stdin:
    pass
和一次讀一行概念一樣, 不過這是用迭代的方式跑完 $stdin$ 檔, 方便的是不用特別處理 $EOF$, 迭代完 $stdin$ 檔就會跳出迴圈。


< $Output \ Optimize$ >
輸出的方法用 $sys$ 模組的 $stdout$,
有以下幾種輸出方法。
1. $stdout.write()$:
from sys import stdout
stdout.write('hello, world\n')
用法整理:
  • 傳入的參數必須為一個字串。
  • 不會自動換行(要自行加上 '\n' 換行字元)。
  • 會回傳所寫的字元總數。
2. $stdout.writelines()$:
用法一:
from sys import stdout
stdout.writelines('hello, world\n')
用法二:
from sys import stdout
stdout.writelines(['hello, ', 'world\n'])
用法整理:
  • 傳入的參數必須是 $iterable$ 的物件。
  • 迭代這個物件的每一個元素並寫入 $stdout$ 檔。
  • 沒有回傳值(回傳值為 $None$)。
  • 如果傳入的參數是字串,$stdout.writelines()$ 的速度遠慢於 $stdout.write()$,應盡量避免。
由於 $PYTHON$ 對於形態之間的轉換方便處理,
所以要節省使用時間的話,
會將每次得到的答案轉成字串形態,
另外存在一個字串或 $list$ 裡,
最後一次輸出。
方法如下:
用法一:
from sys import stdin, stdout
def solution(parameter):
    pass
ans = ''
for s in stdin:
    s = s.strip()
    ans += str(solution(s)) + '\n'
stdout.write(ans + '\n')
用法二:
from sys import stdin, stdout
def solution(parameter):
    pass
ans = []
for s in stdin:
    s = s.strip()
    ans.append(str(solution(s)))
stdout.write('\n'.join(ans) + '\n')


< $Conclusion.$ >
面對一些時限卡很緊的題目,
使用這些方法,
可能因減少讀入/輸出的時間,
而意外的通過了題目。
雖然這些方法,
並不能減少太多執行速度,
但仍不無小補。



以上,
若有更好的想法歡迎提出哦!

留言

熱門文章