优化将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));
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