【问题标题】:Fastest way to decode a hexadecimal digit解码十六进制数字的最快方法
【发布时间】:2015-11-25 20:11:34
【问题描述】:

我正在寻找获取十六进制 ASCII 字符十进制值的最快方法,即保证出现在以下字符串中(可以是小写或大写,但不能有空格):

0123456789ABCDEFabcdef

到目前为止,我想出的最佳公式是:

char c = 'd';  // or any other hex character
int value = (((c & 0x1F) + 9) % 25;

请注意,它是无分支的,但它确实包含昂贵的模运算。

我可以做得更好吗?

【问题讨论】:

  • 所以你想要 d(hex)->13(int)?
  • 如果你想要速度,一个简单的查找表怎么样?它不聪明,但很有用。
  • @MarkusA。我同意它可能不会更快,但是差异在很大程度上取决于您当时的缓存使用情况。这里更重要的是“你测量了吗?”和“接下来谁会阅读你的代码?”
  • 可能更适合代码审查网站。
  • 我认为这在代码审查中不会很好,直到包含更实质性的代码片段作为上下文......此外,没有指定语言。我认为这在 Stack Overflow 上确实更好。

标签: algorithm hex


【解决方案1】:

您可以不使用模数和分支,只需几个移位和减法即可。

int value = (c & 0x0F) + 9 - ((c&0x10)>>1) - ((c&0x10)>>4);

我刚刚从您的公式开始,并使用了 c&0x10 将是 0 用于字母和 0x10 用于 0-9 的事实。

请注意,正如 cmets 中所指出的,通过常量进行 mod 将由编译器优化以进行乘法和加法运算,但这仍然应该稍微好一些,因为编译器没有 c 是十六进制数字的前提条件.

【讨论】:

  • 甜蜜!这就是我所希望的答案! :) 在我接受它之前,我会再给它一点时间,以防其他人想出更聪明的东西。但这已经很棒了! +1
【解决方案2】:

如果您有可用的快速乘法:

int value = (c & 0x0f) + 9 * (c >> 6)

【讨论】:

  • gcc (v5.2.0, x64 target, -O3) 为这一行和 n.m. 的第二个变体生成完全相同的代码。 (因为它知道它可以使用leal (%rax,%rax,8), %eax 来执行该计算。)
【解决方案3】:
(d & 0xf) + ((d & 0x40) >> 3) + ((d & 0x40) >> 6)

非常简单的小技巧。

Demo

略有不同的变体

(d & 0xf) + (d >> 6) + ((d >> 6) << 3)

保存另一个按位and 操作。

两种变体基本上都是将第 6 位乘以 9(与 Mark Ransom 的答案相同,但没有硬件乘法)。

【讨论】:

  • 太棒了!比@toth 的答案少了一个。看起来这个很难被击败。 :)
  • 如果你把d &gt;&gt; 6放到一个临时的,你只需要做一次。希望编译器足够聪明,可以为你做这件事,但是......
  • @MarkRansom 是的,我依靠编译器来优化它。如果不能,那么我以后可能会遇到更大的性能问题。
猜你喜欢
  • 2014-05-13
  • 2020-11-11
  • 1970-01-01
  • 2020-08-28
  • 2018-08-21
  • 2018-01-12
  • 2010-09-27
  • 1970-01-01
相关资源
最近更新 更多