2011-03-15 3 views
2

my previous questionの続きとして、PackedArrayのリスト製品を見つけるSimonの方法は高速ですが、負の値では機能しません。PackedArrayの高速リスト製品サイン?

これは、Absで最小限の時間ペナルティで「修正」することができますが、記号が失われているため、製品記号を別途見つける必要があります。

私が試した最速の方法はEvenQ @ Total @ UnitStep[-lst]

lst = RandomReal[{-2, 2}, 5000000]; 

Do[ 
    [email protected]@UnitStep[-lst], 
    {30} 
] // Timing 

Out[]= {3.062, Null} 

では、より高速な方法はありますか?

答えて

3

[email protected]@@を使用して関連用語を抽出することのナンセンスを除けば、これはソリューションより2倍以上速く、より明確にわかります。各記号の数字要素を数えます。タイミング(出力)を比較するには

EvenQ[-1 /. [email protected]@@[email protected][lst]] 

In[1]:= lst=RandomReal[{-2,2},5000000]; 
     s=t={}; 
     Do[AppendTo[s,[email protected]@UnitStep[-lst]],{10}];//Timing 
     Do[AppendTo[t,EvenQ[-1/[email protected]@@[email protected][lst]]],{10}];//Timing 
     s==t 
Out[3]= {2.11,Null} 
Out[4]= {0.96,Null} 
Out[5]= True 
+0

もう一度やり直してください、Simon。私は「カウント」を試みたが、それは遅かった。私はこの質問を投稿する前に 'Tally'を試してみることに慣れていませんでした。このサイトとその有用な人々は私を怠け者にする可能性があります。 –

+0

@ Mr.Wizard:このサイトでは私も怠惰になっています!時々、私は他の人のMMA問題を私が投稿する前に取るよりも多くの時間を費やしています。 (幸いにも、この場合、「Tally」が私が試した2番目のものでした)。 – Simon

+0

@ Mr.Wizard:StackExchangeサイトの基本モデルが人間の心理学によくマッチすることを示していると思います。 – Simon

1

後半・ツー・パーティのポストビット:あなたは高速で、最終的に興味を持っている場合は、Cコンパイル対象とCompileは約のようです二回速く、これまで掲載最速のソリューションよりも(Tally - Signベース):ここでは

fn = Compile[{{l, _Real, 1}}, 
    Module[{sumneg = 0}, 
    Do[If[i < 0, sumneg++], {i, l}]; 
    EvenQ[sumneg]], CompilationTarget -> "C", 
    RuntimeOptions -> "Speed"]; 

は、私のマシン上のタイミングです:

In[85]:= lst = RandomReal[{-2, 2}, 5000000]; 
s = t = q = {}; 
Do[AppendTo[s, [email protected]@UnitStep[-lst]], {10}]; // Timing 
Do[AppendTo[t, EvenQ[-1 /. Rule @@@ [email protected][lst]]], {10}]; // Timing 
Do[AppendTo[q, fn [lst]], {10}]; // Timing 
s == t == q 

Out[87]= {0.813, Null} 

Out[88]= {0.515, Null} 

Out[89]= {0.266, Null} 

Out[90]= True 
+0

Mmaの素晴らしい点の1つは、通常、命令型のコードを書く必要がないということです。「コンパイル」を使用すると、必然的にそれが破られることになりますが、価値があると思います。とにかく、私は今日のために私の票を使い果たしましたが、すぐにアップアップします! – Simon

+1

@Simon私は、長い間、mmaの手続き的な構造を回避するのに最も面白いことを発見しました。しかし、私がCとJavaでより多くのコーディングを開始したのと同時に、私はまだしばしば最大のスピードを自分のマシンから外さなくてはならない、という認識が変わった。私のための究極の優雅さは、最小の仕事をしている。 mmaでは、ジェネリック関数の背後にロットが隠されているように見えるかもしれません。しかし、この問題では、例えばTallyとSignを適用することは、Cで行われたプリミティブカウントよりもはるかに(CPUの)作業が多いため、スピードアップ(これは本当に美しいソリューションを減らすことではありません)です。 –

+0

@Iは指定しませんでしたが、この方法はMma 7では遅いので、チェックマークを付けることはできません。 –

関連する問題