1

複雑な視覚化を作成するためのログ分析スクリプトがあります。

アクティビティオブジェクトの配列(元々は「ログ」と呼ばれます)を想像してください。各オブジェクトは次の形式になっています。

{
 name:foo,
 activities:[
             {time:t, action:a},
             {time:t, action:a},
             {time:t, action:a},
             ...
            ]
}

配列には最大75のアクティビティオブジェクトがあり、それぞれに400〜600のアクションの配列が含まれます(前日の深夜から5分ごとに1つのタイムスロット)。

既知のアクティビティ名(上記のfoo)と、アクティビティ配列にすでに存在する時刻を指定して、関連するアクションを更新する必要があります。

それぞれの名前は一意であり、毎回正確に5分刻みで配列の昇順になります。

グラフが更新されるたびにこれを1000回強行う必要があるため(つまり、更新する値は平均1000回、プロットする値は1000 * 500 * 60ポイント)、パフォーマンスはかなり重要な問題です...

jqでのループは、私が書くことができるものよりもはるかに効率的であるため、現時点では、

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

$.grep($.grep(log, function(n, i)
 {
  return (n.name == n)
  }
  )[0].activities, function(n, i) 
  {
   return (n.time == t)
  }
 )[0].action = "bar";

それはうまくいっているように見えますが、それは私にとても時間がかかり、私は自信がないほど多くの議論をしました。

私はより良い方法を逃していますか?

4

2 に答える 2

2

loop methodあなたが思いついたループは、最後のものよりも比較的良くなることはないので、私はあなたにあなたの問題に対してより良いものを与えるつもりはありません。

パフォーマンスを向上させるソリューションが本当に必要な場合は、オブジェクトを完全に再配置することを検討する必要があります。name各ログと各アクティビティ配列のすべてtimeが一意である場合は、オブジェクトの設定を変更して、これらの値をとして持つことができますthe key of each subobject

この方法を使用すると、キーの検索を行うだけで、ループは必要ありません。

新しいLOGオブジェクト

  var log =
    {
      unique_name : {
        "activities" : {
          time_1 : action_1,
          time_2 : action_2,
          time_3 : action_3,
          etc...
        }
      },
      unique_name_2 : {
        "activities" : {
          etc...
        }
      }
    }

var u_name = "foo";var t = "some time";あなたは簡単に行うことができます...

log[u_name][t] = "some action";

お役に立てれば!

于 2013-03-14T05:55:56.900 に答える
1

最初に一致したログの最初に一致したアクティビティが必要なようです。

その場合、最初の一致が見つかった後でループを解除する必要があります。これは。で行うことができます.some()

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

log.some(function(ob, i) {
  if (ob.name == n) {
      ob.activities.some(function(ob2, i)  {
          if (ob2.time == t) {
              ob2.action = "bar";
              return true;
          }
      });
      return true;
  }
});

また、nパラメータがn変数をシャドウイングしていたため、パラメータをに変更しましたob


ただし、forループは通常、機能的なメソッドよりもかなり高速です。

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

for (var i = 0; i < log.length; i++) {
  var ob = log[i];
  if (ob.name == n) {
      for (var j = 0; j < ob.activities.length; j++) {
          var ob2 = ob.activities[j];
          if (ob2.time == t) {
              ob2.action = "bar";
              break;
          }
      }
      break;
  }
}


内側のループに一致するものが見つからない場合に外側のループを続行する必要があると判断した場合は、コードを次のいずれかに変更します。

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

log.some(function(ob, i) {
  if (ob.name == n) {
      return ob.activities.some(function(ob2, i)  {
          if (ob2.time == t) {
              ob2.action = "bar";
              return true;
          }
      });
  }
});

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

OUTER:
for (var i = 0; i < log.length; i++) {
  var ob = log[i];
  if (ob.name == n) {
      for (var j = 0; j < ob.activities.length; j++) {
          var ob2 = ob.activities[j];
          if (ob2.time == t) {
              ob2.action = "bar";
              break OUTER;
          }
      }
  }
}
于 2013-03-14T05:46:02.447 に答える