如何高效对[]byte进行16字节序列二分查找?避免[][]byte转换
直接在原始[]byte上实现高效二分查找,避免拆分循环
嘿,我完全懂你不想做那个慢循环的心情——其实根本没必要把整个字节切片拆分成[][]byte再做二分查找!我们可以直接在原始的buf上操作,跳过那个耗时的拆分步骤,同时实现高效的二分查找。
核心思路
因为你的每个IP条目都是固定的16字节,所以二分查找时,我们可以直接通过索引计算出当前要比较的条目在原始buf中的位置,不用提前把所有条目都切出来存到新切片里。这样既节省了内存分配,又省掉了遍历整个切片的时间。
修改后的代码
package main import ( "bytes" "fmt" "io/ioutil" "sort" ) func main() { buf, err := ioutil.ReadFile("bin/test") if err != nil { fmt.Println(err) return } // 先检查buf长度是否是16的倍数(可选,但能避免越界) if len(buf)%16 != 0 { fmt.Println("文件格式错误:不是16字节条目的整数倍") return } // 假设n是你要查找的IP对应的16字节数据 // 这里用一个示例值代替,你可以替换成实际的n.Bytes() target := []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00} // 直接在原始buf上做二分查找 itemCount := len(buf) / 16 idx := sort.Search(itemCount, func(i int) bool { // 计算当前条目在buf中的切片范围 current := buf[i*16 : i*16+16] // 比较当前条目和目标,返回是否大于等于目标(适配sort.Search的逻辑) return bytes.Compare(current, target) >= 0 }) // 检查是否找到匹配项 if idx < itemCount { match := buf[idx*16 : idx*16+16] if bytes.Equal(match, target) { fmt.Printf("找到匹配的IP条目:%v\n", match) } else { fmt.Println("未找到目标IP") } } else { fmt.Println("未找到目标IP") } }
关键细节说明
- 跳过拆分循环:我们直接用
i*16和i*16+16来定位每个16字节条目,完全不需要提前生成data切片,避免了大量的内存拷贝和append操作。 - sort.Search的逻辑:这个函数会返回第一个满足
func(i int) bool条件的索引,所以我们的比较逻辑是判断当前条目是否大于等于目标值,这样就能找到目标在有序切片中的位置(前提是你的文件中的IP条目是按顺序存储的,二分查找要求有序哦)。 - 边界检查:添加了
len(buf)%16 != 0的检查,能提前发现文件格式错误,避免后续切片越界。
这样修改后,你的代码效率会提升很多,尤其是当文件很大的时候,效果会非常明显!
内容的提问来源于stack exchange,提问作者user2626526
相关产品推荐
相关产品推荐

