2016-12-06 8 views
4

全く同じことをする2つの関数はありますが、count()メソッドを使用するメソッドが他のメソッドよりもはるかに高速である理由は誰にも分かりますか? (??私は、それが構築されてどのように動作しない方法を意味する)count()メソッドがforループのpythonよりも高速な理由

可能ならば、私はここで見つかったものよりも理解しやすい答えが欲しい:Algorithm used to implement the Python str.count function または何のソースコードにあります:https://hg.python.org/cpython/file/tip/Objects/stringlib/fastsearch.h

def scoring1(seq): 
    score = 0 
    for i in range(len(seq)): 
     if seq[i] == '0': 
      score += 1  
    return score 

def scoring2(seq): 
    score = 0 
    score = seq.count('0') 
    return score 

seq = 'AATTGGCCGGGGAG0CTTC0CTCC000TTTCCCCGGAAA' 
# takes 1min15 when applied to 100 sequences larger than 100 000 characters 
score1 = scoring1(seq) 
# takes 10 sec when applied to 100 sequences larger than 100 000 characters 
score2 = scoring2(seq) 

返信いただきありがとうございます

+14

Pythonがリリースされて以来、本当に賢い人たちが 'count()'のような関数を組み込んで最適化してきたからです。 –

+0

どのコンピュータでこれを試しましたか?私の方があなたよりも100〜200倍速く見えます。また、索引付けされていないループはなぜですか?あなたは**それをゆっくりとしようとしていましたか? –

+1

[Python str.count関数を実装するために使用されるアルゴリズム](http://stackoverflow.com/questions/16806972/algorithm-used-to-implement-the-python-str-count-function) –

答えて

3

@CodeMonkeyはすでに答えを与えているが、それは、約20%高速に実行されるように、あなたの最初の機能性を向上させることができることに注意することは潜在的に興味深いです:

import time, random 

def scoring1(seq): 
    score=0 
    for i in range(len(seq)): 
     if seq[i]=='0': 
      score+=1  
    return score 

def scoring2(seq): 
    score=0 
    for x in seq: 
     score += (x =='0')  
    return score 

def scoring3(seq): 
    score = 0 
    score = seq.count('0') 
    return score 

def test(n): 
    seq = ''.join(random.choice(['0','1']) for i in range(n)) 
    functions = [scoring1,scoring2,scoring3] 
    for i,f in enumerate(functions): 
     start = time.clock() 
     s = f(seq) 
     elapsed = time.clock() - start 
     print('scoring' + str(i+1) + ': ' + str(s) + ' computed in ' + str(elapsed) + ' seconds') 

test(10**7)  

典型的な出力:

scoring1: 5000742 computed in 0.9651326495293333 seconds 
scoring2: 5000742 computed in 0.7998054195159483 seconds 
scoring3: 5000742 computed in 0.03732172598339578 seconds 

最初の2つのアプローチは両方とも、組み込みのcount()によって吹き飛ばされています。

ストーリーの道徳:あなたがでないときは、で既に最適化された組み込みメソッドを使用すると、独自のコードを最適化する必要があります。

+0

次回は 'timeit'を使います。 –

+0

@Chris_Randsこれはいいアイデアですが、私がボールパークの人物に満足すれば時には' time'を使うことがあります。 –

4

countは基本となるネイティブ実装で実行されるため、 forループは、より遅い解釈コードで実行されます。

関連する問題