【问题标题】:Optimization of algorithm that convert 8-bit number to char8位数字转char算法优化
【发布时间】:2015-10-27 19:09:24
【问题描述】:

我需要将00001110 等8 位数字转换为char。问题很简单,所以我写了代码,一切正常,但现在我需要尽可能地优化速度。

在测试类中:

 class Program
 {
    static void Main(string[] args)
    {
        Random r = new Random();
        int[] testTab = new int[8];
        Normal n = new Normal();
        long time;
        Stopwatch watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < 9000; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                testTab[j] = r.Next(2);
            }
            n.SetTable(testTab);
            n.Decode();
        }
        watch.Stop();
        time = watch.ElapsedTicks;
        Console.WriteLine(time);
        time = watch.ElapsedMilliseconds;
        Console.WriteLine(time);
        Console.ReadKey();
    }
 } 

和算法类:

class Normal
{
    private int[] _tab = new int[8];

    public void SetTable(int[] tab)
    {
        _tab = tab;
    }
    public void Decode()
    {
        char a = ((char)( _tab[0]*1 + _tab[1]*2 + _tab[2]*4 + _tab[3]*8 + _tab[4]*16 + _tab[5]*32 +
                          _tab[6]*64 + _tab[7]*124));
    }
}

在 9000 次的输出中,我得到了 2ms 的时间,这不是很长的时间(对于 9000 ),但我的 PC 中有很好的 proc。

最终代码将在智能手机中运行,因此没有强大的 CPU。在我的算法中,我使用随机数据,在最终版本中,我将通过相机加载数据(因此它会更长)并尝试在一秒钟内重复此操作 10 次,这就是为什么我在最小的操作中也需要最好的时间。

还有比这更快的将字节转换为字符的方法吗?

char a = ((char)( _tab[0]*1 + _tab[1]*2 + _tab[2]*4 + _tab[3]*8 + _tab[4]*16 + _tab[5]*32 + _tab[6]*64 + _tab[7]*128));

【问题讨论】:

  • 为什么要使用int[] 表示比特?这些适合int!了解位操作:&、|、^
  • 为什么不Char result = (Char) (random.Next(256));
  • 我使用 int 是因为我为测试而写,所以我不介意内存只需要时间 int 与字节的速度相同。最后我会尽可能小,但现在只是测试
  • @Aht 顺便说一句:64*2=&gt;128 不是 124
  • 真实数据从何而来?你真的需要二进制字符串吗?

标签: c# .net char


【解决方案1】:

值得一试:

var yourString = "00100000";
char yourChar = (char) Convert.ToByte(yourString, 2); // you got ' ' (space)

它可能更快也可能不会更快,但绝对更简单、更稳定、更易于维护。

【讨论】:

  • 这会将 char 转换为 byte ?我需要将字节转换为字符:D
  • 这会将 8 位数字的字符串表示形式转换为 char,这正是您所要求的。
【解决方案2】:

tl;dr您的转换代码已经很高效,不是您的瓶颈。


您的基准测试存在缺陷。您不仅仅是在计时将存储在int[] 中的二进制转换为整数值。您还在为随机数据的生成计时。我希望大部分时间都花在生成随机数据上。

重新编写您的基准测试程序,以对开始计时之前准备好的数据进行操作。确保测试的持续时间至少为 5 或 10 秒,以便您生成有意义的答案。如果只运行两毫秒,那么计时器的粒度会影响结果的质量。

请记住,在您的实际应用程序中,您将在 QR 码的相机上拍照并对其进行解码。其成本比转换 8 位 int 数组的成本高出许多数量级。

您执行该转换的代码已经很高效了。不要寻求进一步优化它。不仅没有必要优化它,而且获得显着收益的希望很小。为了清晰和简洁起见,您可能会选择使用执行此类转换的 .net 库方法之一,但程序这部分的性能不是问题。

顺便说一句,您似乎需要将 8 位值转换为字节,将这些值添加到字节数组中,然后提供给 Encoding.GetString 以获取您的文本。根据您的代码强制转换为 UTF-16 char 是不正确的。

【讨论】:

  • 我知道这个基准测试很糟糕。我写了这个。我知道必须解码 QR,制作图片,制作一些照片,这比将位转换为 char 需要更长的时间,但是当我细化我的代码时,我尝试在每个部分都让它快速,这就是我从最小部分开始的原因。但是,如果你说我不会在这篇文章中获得实时,我说好的,我相信你 :) 我想我会在转换照片时回来(这必须优化完美,所以我需要专家的帮助 :))
  • 学习识别瓶颈并首先优化它们很重要。这样做直到性能可以接受。优化不是瓶颈的代码是浪费大量时间,因为您将无法观察到任何改进,并且您可能会使您的代码更难阅读和维护。过早的优化通常会让你的代码变得更糟。
  • 我会记住这个建议
【解决方案3】:

我用不同的实现运行了一些测试。 首先是@Melnikovl 的回答。 第二个是我的,我用| 替换了+,用&lt;&lt; 运算符替换了*。 第三是作者的原始解决方案。

我用修改后的代码进行了测试,只测量了转换代码。 第一个和第二个解决方案表现出更好的性能。但是BitConverter 多一点会更好,所以我认为你应该选择它(也是因为如果代码简单的话)

【讨论】:

    【解决方案4】:
    var byte[] bytes = { 1, 1, 1, 1 };
    int i = BitConverter.ToInt32(bytes, 0);
    char a = (char)i;
    

    别忘了检查字节数组是小端还是大端

    【讨论】:

    • 可能是因为没有覆盖perf的问题?
    • @DavidHeffernan 值得评论并询问作者,但否决?它仍然回答了这个问题。它比其他的做得更好(从字符串转换)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 2023-02-03
    相关资源
    最近更新 更多