许多 Java 书籍都将switch
语句描述为比if else
语句更快。但我没有发现为什么 switch 比 if 快。
例子
我有一种情况,我必须从两项中选择一项。我可以使用任何一种使用
switch (item) {
case BREAD:
//eat Bread
break;
default:
//leave the restaurant
}
或者
if (item == BREAD) {
//eat Bread
} else {
//leave the restaurant
}
考虑到 item 和 BREAD 是一个常量 int 值。
在上面的例子中哪个动作更快,为什么?
因此,如果您计划拥有大量数据包,那么现在内存并不是一个很大的成本,而且数组非常快。您也不能依赖 switch 语句来自动生成跳转表,因此自己生成跳转表场景会更容易。正如您在下面的示例中看到的,我们假设最多 255 个数据包。
为了得到下面的结果,你需要抽象......我不会解释它是如何工作的,所以希望你对此有所了解。
如果您需要更多,我将其更新为将数据包大小设置为 255,然后您必须对 (id < 0) || 进行边界检查 (ID > 长度)。
Packets[] packets = new Packets[255]; static { packets[0] = new Login(6); packets[2] = new Logout(8); packets[4] = new GetMessage(1); packets[8] = new AddFriend(0); packets[11] = new JoinGroupChat(7); // etc... not going to finish. } public void handlePacket(IncomingData data) { int id = data.readByte() & 0xFF; //Secure value to 0-255. if (packet[id] == null) return; //Leave if packet is unhandled. packets[id].execute(data); }
编辑因为我在 C++ 中使用了很多跳转表,现在我将展示一个函数指针跳转表的例子。这是一个非常通用的示例,但我确实运行了它并且它工作正常。请记住,您必须将指针设置为 NULL,C++ 不会像在 Java 中那样自动执行此操作。
#include <iostream> struct Packet { void(*execute)() = NULL; }; Packet incoming_packet[255]; uint8_t test_value = 0; void A() { std::cout << "I'm the 1st test.\n"; } void B() { std::cout << "I'm the 2nd test.\n"; } void Empty() { } void Update() { if (incoming_packet[test_value].execute == NULL) return; incoming_packet[test_value].execute(); } void InitializePackets() { incoming_packet[0].execute = A; incoming_packet[2].execute = B; incoming_packet[6].execute = A; incoming_packet[9].execute = Empty; } int main() { InitializePackets(); for (int i = 0; i < 512; ++i) { Update(); ++test_value; } system("pause"); return 0; }
另外我想提的另一点是著名的分而治之。所以我上面 255 个数组的想法可以减少到不超过 8 个 if 语句作为最坏的情况。
即但请记住,它会变得混乱且难以快速管理,而我的其他方法通常更好,但这在数组无法削减它的情况下使用。您必须弄清楚您的用例以及每种情况何时效果最佳。就像如果您只有一些检查,您就不会想要使用这两种方法中的任何一种一样。
If (Value >= 128) { if (Value >= 192) { if (Value >= 224) { if (Value >= 240) { if (Value >= 248) { if (Value >= 252) { if (Value >= 254) { if (value == 255) { } else { } } } } } } } }