【问题标题】:C# convert an ArrayList of type ints into a Point[]C# 将整数类型的 ArrayList 转换为 Point[]
【发布时间】:2011-08-11 22:51:39
【问题描述】:

首先,我在使用 CE6.5 的移动设备上运行它。我有一个整数数据的 ArrayList,出于绘图目的,我想按顺序将其转换为列表中的数字,并将 int 值转换为点的 x 和 y 值。将所有这些点放入一个点数组中,然后使用 bufferedGraphics.DrawLines 将其绘制到表单上。我有一种方法似乎工作得很快,但不确定这是否是最好的方法。对此代码有何建议或改进?

哦,是的,dataList 通常约为 450 或更多,具体取决于屏幕大小和旋转。

public Point[] toPointArray(int w, int h) {
      Point[] p;
      int val;

      p = new Point[dataList.Count];
      for (int i = 0; i < dataList.Count; i++) {
          val = (int)dataList[i];
          if (i < p.Length)
               p[i] = new Point(i, h - (val * h) / range + (min * h) / range);
      }
      return p;
}

我的一些数据正在以每秒 256 次的速度更新 dataList,因此存在覆盖问题,但到目前为止,即使在这些速度下,这似乎也有效。

以下是当前速度的一些速度值,时间以秒为单位:

Time to complete 0.000588
Time to complete 0.0005886154
Time to complete 0.0005846154
Time to complete 0.0005870769
Time to complete 0.0005830769
Time to complete 0.0005806154
Time to complete 0.0005981539
Time to complete 0.0007206154
Time to complete 0.0005836923
Time to complete 0.001039077

从下面的答案中得到建议后,我的代码现在看起来像这样,平均执行时间为 0.00047 秒。 dataList 是一个全局的,现在是一个 List 而不是 ArrayList,(int) 转换占用了原始处理时间的四分之一。

   List<int> dataList = new List<int>();

   public Point[] toPointArray(int w, int h) {
        Point[] p = new Point[dataList.Count];
        for (int i = 0; i < dataList.Count; i++) {
            p[i] = new Point(i, h - (dataList[i] * h) / range + (min * h) / range);
        }

        return p;
    }

【问题讨论】:

  • 您可以删除if,它会稍微提高性能。

标签: c# mobile compact-framework arraylist point


【解决方案1】:

编辑 - 在对索引和字典发表评论后:

Point[] p = (from i in Enumerable.Range(0, dataList.Count) 
             select new Point(
                        i, 
                        h - (((int)dataList[i]) * h) / range + (min * h) / range))
            .OrderBy ((pp) => pp.X)
            .ToArray();

这适用于ArrayList 等。

【讨论】:

  • 这将采用等于 25 的 dataList[0] 的索引并将其转换为 Point(0, h - (25* h) / range + (min * h) / range) ?
  • 不,它不会...如果 dataList 是 Dictionary 可以做到 - 有可能吗?
  • 目前不可行,太多代码无法将其撕掉并将所有内容更改为字典。
  • 使用他的方法虽然它吸引了我优雅的一面,但实际上比我的原始代码慢...为了美观,这段代码很震撼,但为了速度,它实际上慢了近 10 倍...执行时间平均为 0.006785356 秒。而我的原始代码是 0.0009 秒。
【解决方案2】:

1) 在您使用它们的同一位置声明变量。无需单独声明 Point[] a (它是在那之后创建的),也没有理由单独声明 int val (它不在循环之外使用,并且在使用它的地方声明它没有性能损失)。
2) 你知道 i 是 3) 使用 LINQ
4) 使用微软建议的命名标准(ProperCase for methods)
5) 使用更好的变量名
6) 使用更好的方法名称 - 此方法不会将其转换为数组(或者至少,这不是该方法的主要目的)
7) 使用类型化的数据存储。我们看不到 dataList 是什么,但您不必将其转换为 int(除非您知道它是 int 或类似的 long)

如果您可以使用 LINQ,我还没有查看 Yahia 的解决方案,但它应该可以工作。如果您不能/不想使用 LINQ,请尝试:

public Point[] ToPointGrid(int width, int height)
{
  Point[] points = new Point[dataList.Count];
  for(int index = 0; index < dataList.Count; ++index)
  {
    points[index] = new Point(index, height - (dataList[index] * height) / range + (minimum * height) / range);
  }
  return points;
}

【讨论】:

  • dataList 是 ArrayList 类型,添加到它的值是 int 类型,因此进行强制转换,因为 ArrayList 返回 Object 类型的值。
  • @JPM - 我相信@Kyle 说dataList 应该尽可能转换为强类型List&lt;int&gt;
  • 我不同意#4、#5、#6,因为这与速度无关,而且我们使用与 MS 不同的命名约定。
  • 您并没有专门要求仅提供有关速度的建议。另外,我怀疑您的命名约定指定使用 1 个字母的名称。那些永远不可读。
  • 触摸是的,你是对的,我应该说我可以加快速度...感谢您的帮助,尽管我能够使用 #1、#2 和 #7 并且看到了改进速度几乎翻了一番 这是我原始代码的时间...0.000947304 秒,这是您提出建议的时间 0.000493501 秒
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 2012-07-05
  • 2011-01-01
  • 1970-01-01
相关资源
最近更新 更多