(0) 「なぜ win32com は xlrd よりもずっと遅いのですか?」と尋ねました。... この質問は、「妻を殴るのをやめましたか?」に少し似ています。--- それは真実ではないかもしれない前提に基づいています。win32com は優秀なプログラマーによって C で作成されましたが、xlrd は平均的なプログラマーによって純粋な Python で作成されました。本当の違いは、win32com は COM を呼び出さなければならないということです。COM はプロセス間通信を含み、あなたが知っている人によって書かれましたが、xlrd は Excel ファイルを直接読み込んでいます。さらに、シナリオには 4 人目のパーティ、YOU が登場します。読み進めてください。
find_last_col()
(1) COM コードで繰り返し使用する関数のソースを示していない。xlrd コードでは、常に同じ値 (ws.ncols) を使用できます。したがって、COM コードでは、find_last_col(ws)
ONCE を呼び出してから、返された結果を使用する必要があります。更新COMからxlrdに相当するものを取得する方法については、別の質問への回答を参照してくださいSheet.ncols
。
(2) 各セル値に 2 回アクセスすると、両方のコードの速度が低下します。それ以外の
if ws.cell_value(6, cnum):
wsHeaders[str(ws.cell_value(6, cnum))] = (cnum, ws.ncols)
試す
value = ws.cell_value(6, cnum)
if value:
wsHeaders[str(value)] = (cnum, ws.ncols)
注: 各コード スニペットには 2 つのケースがあります。
(3) ネストされたループの目的はまったく明らかではありませんが、COM からの冗長なフェッチを含む、冗長な計算がいくつかあるようです。何を達成しようとしているのかを例を挙げて教えていただければ、それをより速く実行できるようにお手伝いできるかもしれません。少なくとも、COM から値を一度抽出して、Python のネストされたループで処理する方が高速です。柱は何本ありますか?
更新 2一方、小さなエルフは直腸鏡を使用してコードを読み、次のスクリプトを思いつきました。
tests= [
"A/B/C/D",
"A//C//",
"A//C//E",
"A///D",
"///D",
]
for test in tests:
print "\nTest:", test
row = test.split("/")
ncols = len(row)
# modelling the OP's code
# (using xlrd-style 0-relative column indexes)
d = {}
for cnum in xrange(ncols):
if row[cnum]:
k = row[cnum]
v = (cnum, ncols) #### BUG; should be ncols - 1 ("inclusive")
print "outer", cnum, k, '=>', v
d[k] = v
for cend in xrange(cnum + 1, ncols):
if row[cend]:
k = row[cnum]
v = (cnum, cend - 1)
print "inner", cnum, cend, k, '=>', v
d[k] = v
break
print d
# modelling a slightly better algorithm
d = {}
prev = None
for cnum in xrange(ncols):
key = row[cnum]
if key:
d[key] = [cnum, cnum]
prev = key
elif prev:
d[prev][1] = cnum
print d
# if tuples are really needed (can't imagine why)
for k in d:
d[k] = tuple(d[k])
print d
これはこれを出力します:
Test: A/B/C/D
outer 0 A => (0, 4)
inner 0 1 A => (0, 0)
outer 1 B => (1, 4)
inner 1 2 B => (1, 1)
outer 2 C => (2, 4)
inner 2 3 C => (2, 2)
outer 3 D => (3, 4)
{'A': (0, 0), 'C': (2, 2), 'B': (1, 1), 'D': (3, 4)}
{'A': [0, 0], 'C': [2, 2], 'B': [1, 1], 'D': [3, 3]}
{'A': (0, 0), 'C': (2, 2), 'B': (1, 1), 'D': (3, 3)}
Test: A//C//
outer 0 A => (0, 5)
inner 0 2 A => (0, 1)
outer 2 C => (2, 5)
{'A': (0, 1), 'C': (2, 5)}
{'A': [0, 1], 'C': [2, 4]}
{'A': (0, 1), 'C': (2, 4)}
Test: A//C//E
outer 0 A => (0, 5)
inner 0 2 A => (0, 1)
outer 2 C => (2, 5)
inner 2 4 C => (2, 3)
outer 4 E => (4, 5)
{'A': (0, 1), 'C': (2, 3), 'E': (4, 5)}
{'A': [0, 1], 'C': [2, 3], 'E': [4, 4]}
{'A': (0, 1), 'C': (2, 3), 'E': (4, 4)}
Test: A///D
outer 0 A => (0, 4)
inner 0 3 A => (0, 2)
outer 3 D => (3, 4)
{'A': (0, 2), 'D': (3, 4)}
{'A': [0, 2], 'D': [3, 3]}
{'A': (0, 2), 'D': (3, 3)}
Test: ///D
outer 3 D => (3, 4)
{'D': (3, 4)}
{'D': [3, 3]}
{'D': (3, 3)}