需要优化计数正负值

我需要优化计算pos / neg值的代码并按时间删除不合格的值。

我有附加时间戳的值队列。
我需要丢弃1ms的值并计算负值和正值。 这是伪代码

list l; v = q.dequeue(); deleteold(l, v.time); l.add(v); negcount = l.count(i => i.value  i.value >= 0); if(negcount == 10) return -1; if(poscount == 10) return 1; 

我需要在c#中以最大速度运行此代码。 无需坚持清单。 事实上,欢迎以neg和pos值分隔的数组。

编辑:可能不安全的数组将是最好的。 任何提示?

编辑:感谢抬头..我很快测试了arrays版本与列表(我已经拥有)并且列表更快:35毫秒与16毫秒的1密耳迭代……

以下是公平的代码:

 class Program { static int LEN = 10; static int LEN1 = 9; static void Main(string[] args) { Var[] data = GenerateData(); Stopwatch sw = new Stopwatch(); for (int i = 0; i < 30; i++) { sw.Reset(); ArraysMethod(data, sw); Console.Write("Array: {0:0.0000}ms ", sw.ElapsedTicks / 10000.0); sw.Reset(); ListMethod(data, sw); Console.WriteLine("List: {0:0.0000}ms", sw.ElapsedTicks / 10000.0); } Console.ReadLine(); } private static void ArraysMethod(Var[] data, Stopwatch sw) { int signal = 0; int ni = 0, pi = 0; Var[] n = new Var[LEN]; Var[] p = new Var[LEN]; for (int i = 0; i < LEN; i++) { n[i] = new Var(); p[i] = new Var(); } sw.Start(); for (int i = 0; i < DATALEN; i++) { Var v = data[i]; if (v.val < 0) { int x = 0; ni = 0; // time is not sequential for (int j = 0; j < LEN; j++) { long diff = v.time - n[j].time; if (diff  10000) x = j; else ni++; } n[x] = v; if (ni >= LEN1) signal = -1; } else { int x = 0; pi = 0; // time is not sequential for (int j = 0; j < LEN; j++) { long diff = v.time - p[j].time; if (diff  10000) x = j; else pi++; } p[x] = v; if (pi >= LEN1) signal = 1; } } sw.Stop(); } private static void ListMethod(Var[] data, Stopwatch sw) { int signal = 0; List d = new List(); sw.Start(); for (int i = 0; i < DATALEN; i++) { Var v = data[i]; d.Add(new Var() { time = v.time, val = v.val < 0 ? -1 : 1 }); // delete expired for (int j = 0; j < d.Count; j++) { if (v.time - d[j].time < 10000) d.RemoveAt(j--); else break; } int cnt = 0; int k = d.Count; for (int j = 0; j = 0 ? cnt : -cnt) >= LEN) signal = 9; } sw.Stop(); } static int DATALEN = 1000000; private static Var[] GenerateData() { Random r = new Random(DateTime.Now.Millisecond); Var[] data = new Var[DATALEN]; Var prev = new Var() { val = 0, time = DateTime.Now.TimeOfDay.Ticks}; for (int i = 0; i < DATALEN; i++) { int x = r.Next(20); data[i] = new Var() { val = x - 10, time = prev.time + x * 1000 }; } return data; } class Var { public int val; public long time; } } 

一些想法:

  1. 只计算直到max(negcount,poscount)变为10,然后退出(不需要计算其余的)。 仅当10是最大计数时才有效。
  2. 计算一次性消极和正面项目。
  3. 只计算negcount并从count-negcount推断poscount,这比计算它们更容易。

它们中的任何一个是否比现在更快,哪个更快,取决于数据通常的样子。 是长吗? 短?

更多关于3:
您可以使用欺骗来避免分支。 您不必测试该项目是否为负数,您可以将其否定性添加到计数器中。 假设项是x并且它是intx >> 31对于正x是0而对于负x是-1。 所以counter -= x >> 31将给出negcount

编辑:不安全的数组可以更快,但不应该在这种情况下,因为循环将是forms

 for (int i = 0; i < array.Length; i++) do something with array[i]; 

这是由JIT编译器优化的。

要获得negcount和poscount,您将遍历整个列表两次。 相反,遍历它一次(计算negcount),然后poscount = l.Count – negcount。