使用数字模式的 Switch 语句
Switch statement using numeric patterns
我正在尝试为给定值创建一个 switch 语句。该值是一个 16 位无符号数,我想跳转到适当的模式。每个模式都是一个十六进制字符串,但下划线表示通配符。例如,(0x1234 匹配“1234”和“12_4”但不匹配“56_8”)。虽然我只发布了这些模式的一个子集,但假设它们涵盖了 0x0000-0xFFFF 的整个范围。
patterns = {
'15__': foo,
'2__0': bar,
'8__0': baz,
...
}
...
def run(self, x: int) -> None:
# x to string (0x567f -> "567F")
x_str = str(hex(opcode))[2:].zfill(4).upper()
# Search for the matching pattern and execute the associated method
for pattern, instruction in patterns.items():
if all([x_str[i] == pattern[i] for i in range(len(pattern)) if pattern[i] != '_'):
instruction(x)
break
现在,这行得通了。然而,它非常慢,并且违背了使用字典的目的,因为它只是遍历它。此外,由于它必须将 x 转换为字符串(带格式),然后根据模式字符串检查该字符串,所以整个过程是一个巨大的瓶颈。我正在寻找一种方法,最好是让它更接近实际查找 table,如果我们不需要将 x 转换为字符串,则加分。
这种类型的 switch 语句是一个迭代过程,而不是跳转table。在您提出的一般情况下,避免迭代的方法是根据 table.
中常见数字(hexits)和通配符的特定排列生成部分索引决策图
相反,尝试简单地加快匹配速度。我建议您对 table 键采用掩码匹配方法。分别对“无关”(通配符)位置进行编码,并将键保存为匹配值和掩码值的元组。你的例子是
patterns = {
(0x1500, 0xFF00): foo,
(0x2000, 0xF00F): bar,
(0x8000, 0xF00F): baz,
...
}
要根据候选 cand
检查特定密钥,您需要寻找位相等性,但要屏蔽通配符位置中的任何不匹配:
cand ^ match # bit inequality; mismatch is 1
result & mask # force don't-care bits to 0
以便您检查
if (cand ^ match) & mask:
continue # Something doesn't match
else:
return value from dict
你的字典格式是
(match, mask): value
你能处理迭代和 return 值的逻辑吗?
我正在尝试为给定值创建一个 switch 语句。该值是一个 16 位无符号数,我想跳转到适当的模式。每个模式都是一个十六进制字符串,但下划线表示通配符。例如,(0x1234 匹配“1234”和“12_4”但不匹配“56_8”)。虽然我只发布了这些模式的一个子集,但假设它们涵盖了 0x0000-0xFFFF 的整个范围。
patterns = {
'15__': foo,
'2__0': bar,
'8__0': baz,
...
}
...
def run(self, x: int) -> None:
# x to string (0x567f -> "567F")
x_str = str(hex(opcode))[2:].zfill(4).upper()
# Search for the matching pattern and execute the associated method
for pattern, instruction in patterns.items():
if all([x_str[i] == pattern[i] for i in range(len(pattern)) if pattern[i] != '_'):
instruction(x)
break
现在,这行得通了。然而,它非常慢,并且违背了使用字典的目的,因为它只是遍历它。此外,由于它必须将 x 转换为字符串(带格式),然后根据模式字符串检查该字符串,所以整个过程是一个巨大的瓶颈。我正在寻找一种方法,最好是让它更接近实际查找 table,如果我们不需要将 x 转换为字符串,则加分。
这种类型的 switch 语句是一个迭代过程,而不是跳转table。在您提出的一般情况下,避免迭代的方法是根据 table.
中常见数字(hexits)和通配符的特定排列生成部分索引决策图相反,尝试简单地加快匹配速度。我建议您对 table 键采用掩码匹配方法。分别对“无关”(通配符)位置进行编码,并将键保存为匹配值和掩码值的元组。你的例子是
patterns = {
(0x1500, 0xFF00): foo,
(0x2000, 0xF00F): bar,
(0x8000, 0xF00F): baz,
...
}
要根据候选 cand
检查特定密钥,您需要寻找位相等性,但要屏蔽通配符位置中的任何不匹配:
cand ^ match # bit inequality; mismatch is 1
result & mask # force don't-care bits to 0
以便您检查
if (cand ^ match) & mask:
continue # Something doesn't match
else:
return value from dict
你的字典格式是
(match, mask): value
你能处理迭代和 return 值的逻辑吗?