优化将8位数字转换为字符的算法

本文关键字:字符 算法 转换 8位 数字 优化 | 更新日期: 2023-09-27 18:06:21

我需要将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(,但我在我的电脑中有很好的过程。

最后的代码将在智能手机中运行,因此没有强大的CPU。在我的算法中,我使用随机数据,在最终版本中,我将通过Camera加载数据(因此数据会更长(,并尝试在一秒内重复此操作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));

优化将8位数字转换为字符的算法

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


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

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

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

进行转换的代码已经很有效了。不要试图进一步优化它。不仅没有必要对其进行优化,而且取得重大成果的希望也很小。为了简洁明了,您可以选择使用执行此类转换的.net库方法之一,但程序的这一部分的性能不是问题。

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

值得一试:

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

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

我用不同的实现运行了一些测试。首先是@Melnikovl的回答。第二个是我的,我用|替换了+,用<<操作符替换了*。第三是作者独创的解决方案。

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

var byte[] bytes = { 1, 1, 1, 1 };
int i = BitConverter.ToInt32(bytes, 0);
char a = (char)i;

不要忘记检查字节数组litte还是big-endian