4

仮に、イベント値をイベントリスナーに送信する10の異なるボタンの押下を説明するために1つのifステートメントを使用しているとしましょう。

public boolean onTouch(int v) { //this is my only listener for all ten buttons
  if(event.getAction() == MotionEvent.ACTION_DOWN){
   if(v==button_one){pool.play(bass1, 1f,1f, 1, 0, 1f);}
   if(v==button_two){pool.play(bass2, 1f,1f, 1, 0, 1f);}
   if(v==button_three){pool.play(bass3, 1f,1f, 1, 0, 1f);}
   if(v==button_four){pool.play(snare1, 1f,1f, 1, 0, 1f);}
   if(v==button_five){pool.play(snare2, 1f,1f, 1, 0, 1f);}
   if(v==button_six){pool.play(snare3, 1f,1f, 1, 0, 1f);}
   if(v==button_seven){pool.play(hh1, 1f,1f, 1, 0, 1f);}
   if(v==button_eight){pool.play(hh2, 1f,1f, 1, 0, 1f);}
 }
 return false;
}

これらを分類する方が効率的でしょうか?たとえば、スネア用に1つ、ベース用に1つ、ハイハット用に1つのonClickイベントがあるため、ボタンが押されたときにプログラムが各ifステートメントをカウントする必要はなく、発射されたリスナー内にあるものだけがカウントされます。イベント?

4

6 に答える 6

5

このようなものはどうですか?

HashMap<int,int>  soundMap = new HashMap<int,int>();
soundMap.put(button_one, bass1);
soundMap.put(button_two, bass2);
soundMap.put(button_three, bass3);
soundMap.put(button_four, snare1);
soundMap.put(button_five, snare2);
soundMap.put(button_six, snare3);
soundMap.put(button_seven, hh1);
soundMap.put(button_eight, hh2);

HashMap をクラス変数として持ち、マッピングを onCreate などで初期化します。次に、これをリスナーに使用できます。

public boolean onTouch(int v) {
    if(event.getAction() == MotionEvent.ACTION_DOWN) {
        pool.play(soundMap.get(v), 1f, 1f, 1, 0, 1f);
    }
    return false;
}

これの利点は、将来さらにボタンを追加する必要がある場合に、新しいサウンド マッピングを使用してマップの初期化メソッドを変更するだけでよいことです。リスナーを変更する必要はありません。

于 2012-05-25T14:10:43.953 に答える
1

ここでの豊富なアドバイスと意見に加えて、「それは本当にパフォーマンスの問題なのか」についてのこれまでのすべてに同意するために、私はコードを読みやすく、維持しやすくする構造を採用します。維持する必要があるかもしれません。メンテナンスに伴い、延長も考えます。さらに5つのサウンドパッドを追加したい場合、3か月後に何が起こるでしょうか?

行数を最小限に抑えると、ほぼ計り知れないほどのパフォーマンスが向上し、APK で数バイトを節約できますが、ほとんどの場合、読みやすさと引き換えにそれを行います。

とはいえ、私はkcoppocksのソリューションが好きです。私にとっては、それは甘くてエレガントで、私ならどうするかですが、経験のレベルが異なり、それを見て「ああ、わかりました」と言うことができない場合は、あなたのifsを保持するか、またはより良い、スイッチ。

于 2012-05-25T14:33:15.150 に答える
0

この場合、パフォーマンスについて心配する価値はありません。条件ステートメントにかかる時間は、その周りのイベント処理コードによって完全に小さくなります。パフォーマンスの第 1 から第 3 の法則は、測定、測定、測定であり、私は違いを見つける可能性について懐疑的です。

変更されているのは、pool.play の最初の引数だけであることに気付きます。bass1、bass2 などと対応する v 値の間に関係はありますか?

于 2012-05-25T14:16:23.533 に答える
0

必要だとは思いませんが、スイッチとケースを強くお勧めします。最も一般的なものから最も一般的でないものまで並べることができますが、それは気付かれないような小さな変更です。これらの if ステートメントを実行するのに、それほど時間はかかりません。

于 2012-05-25T14:16:43.397 に答える
0

それが問題であることがわかるまで、私はそれを分割することを心配しません. スイッチは、繰り返されるifステートメントを減らすのに役立ちます。

public boolean onTouch(int v) {
  if(event.getAction() == MotionEvent.ACTION_DOWN) {
    switch (v) {
    case button_one: pool.play(); break;
    case button_two: pool.play(..); break;
    ...
    }
  }
 return false;
}
于 2012-05-25T14:05:53.780 に答える
0

これが何回実行されるかはわかりifませんが、非効率的ではないようです。このブール値テストは非常に高速です。とにかく、できるだけ効率的にしたい場合は、次の 2 つのオプションがあります。

  1. 簡単なもの: のelse if代わりに使用しifます。
  2. 複雑なもの:ActionIfオブジェクトの配列を使用して、必要なことを行います。

public interface ActionIf {
    public void go();
}

public class ActionBass1 implements ActionIf {
    @Override
    public void go() {
        pool.play(bass1, 1f,1f, 1, 0, 1f);
    }
}

public class ActionBass2 implements ActionIf {
    @Override
    public void go() {
        pool.play(bass2, 1f,1f, 1, 0, 1f);
    }
}

...

public ActionIf[] actions = {new ActionBass1(), new Action Bass2(), ...);

public boolean onTouch(int v) { //this is my only listener for all ten buttons
    if(event.getAction() == MotionEvent.ACTION_DOWN && v >= 0 && v <= (button_eight-button_one)){
        actions[button_one+v].go();
    }
    return false;
}

于 2012-05-25T14:18:48.197 に答える