mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 14:06:44 +08:00

根据静态分析结果清理未使用的函数: 删除文件: - Common/utils/mappool.go (整个Map对象池模块未被使用) 精简文件: - Common/utils/slicepool.go: 移除未使用的池管理函数,保留核心去重功能 - Common/utils/stringbuilder.go: 移除未使用的格式化和统计函数 - Common/utils/benchmark_test.go: 更新测试以适应清理后的API 保留的核心功能: ✓ JoinStrings/JoinInts - 字符串连接优化 (18x性能提升) ✓ DeduplicateStrings - 字符串去重功能 ✓ StringBuilderPool - 字符串构建器池化机制 清理效果: - 减少约150行无用代码 - 简化API设计,提高可维护性 - 保持所有实际使用的优化功能完整性 - 编译测试和功能测试全部通过 经验证,核心的内存优化功能(字符串连接18x性能提升,99.8%内存减少)完全保留。
315 lines
7.2 KiB
Go
315 lines
7.2 KiB
Go
package utils
|
||
|
||
import (
|
||
"fmt"
|
||
"runtime"
|
||
"strings"
|
||
"testing"
|
||
"time"
|
||
)
|
||
|
||
// BenchmarkStringJoinOriginal 原始字符串连接方法
|
||
func BenchmarkStringJoinOriginal(b *testing.B) {
|
||
slice := make([]string, 100)
|
||
for i := range slice {
|
||
slice[i] = fmt.Sprintf("item-%d", i)
|
||
}
|
||
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
var result string
|
||
if len(slice) > 0 {
|
||
result = slice[0]
|
||
for j := 1; j < len(slice); j++ {
|
||
result += "," + slice[j]
|
||
}
|
||
}
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// BenchmarkStringJoinOptimized 优化后的字符串连接方法
|
||
func BenchmarkStringJoinOptimized(b *testing.B) {
|
||
slice := make([]string, 100)
|
||
for i := range slice {
|
||
slice[i] = fmt.Sprintf("item-%d", i)
|
||
}
|
||
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
result := JoinStrings(slice, ",")
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// BenchmarkIntJoinOriginal 原始整数连接方法
|
||
func BenchmarkIntJoinOriginal(b *testing.B) {
|
||
slice := make([]int, 100)
|
||
for i := range slice {
|
||
slice[i] = i * 10
|
||
}
|
||
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
var result string
|
||
if len(slice) > 0 {
|
||
result = fmt.Sprintf("%d", slice[0])
|
||
for j := 1; j < len(slice); j++ {
|
||
result += "," + fmt.Sprintf("%d", slice[j])
|
||
}
|
||
}
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// BenchmarkIntJoinOptimized 优化后的整数连接方法
|
||
func BenchmarkIntJoinOptimized(b *testing.B) {
|
||
slice := make([]int, 100)
|
||
for i := range slice {
|
||
slice[i] = i * 10
|
||
}
|
||
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
result := JoinInts(slice, ",")
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// BenchmarkDeduplicateOriginal 原始去重方法
|
||
func BenchmarkDeduplicateOriginal(b *testing.B) {
|
||
slice := make([]string, 1000)
|
||
for i := range slice {
|
||
slice[i] = fmt.Sprintf("item-%d", i%100) // 10倍重复
|
||
}
|
||
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
temp := make(map[string]struct{})
|
||
var result []string
|
||
|
||
for _, item := range slice {
|
||
if _, exists := temp[item]; !exists {
|
||
temp[item] = struct{}{}
|
||
result = append(result, item)
|
||
}
|
||
}
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// BenchmarkDeduplicateOptimized 优化后的去重方法
|
||
func BenchmarkDeduplicateOptimized(b *testing.B) {
|
||
slice := make([]string, 1000)
|
||
for i := range slice {
|
||
slice[i] = fmt.Sprintf("item-%d", i%100) // 10倍重复
|
||
}
|
||
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
result := DeduplicateStrings(slice)
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// BenchmarkSliceAllocationOriginal 原始切片分配方法
|
||
func BenchmarkSliceAllocationOriginal(b *testing.B) {
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
var result []string
|
||
for j := 0; j < 50; j++ {
|
||
result = append(result, fmt.Sprintf("item-%d", j))
|
||
}
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// BenchmarkSliceAllocationOptimized 优化后的切片分配方法
|
||
func BenchmarkSliceAllocationOptimized(b *testing.B) {
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
result := make([]string, 0, 50)
|
||
for j := 0; j < 50; j++ {
|
||
result = append(result, fmt.Sprintf("item-%d", j))
|
||
}
|
||
_ = result
|
||
}
|
||
}
|
||
|
||
// TestMemoryUsage 内存使用情况对比测试
|
||
func TestMemoryUsage(t *testing.T) {
|
||
// 测试字符串连接的内存使用
|
||
t.Run("StringJoin", func(t *testing.T) {
|
||
slice := make([]string, 1000)
|
||
for i := range slice {
|
||
slice[i] = fmt.Sprintf("test-string-%d", i)
|
||
}
|
||
|
||
// 测试原始方法
|
||
runtime.GC()
|
||
var m1, m2 runtime.MemStats
|
||
runtime.ReadMemStats(&m1)
|
||
|
||
for i := 0; i < 1000; i++ {
|
||
var result string
|
||
if len(slice) > 0 {
|
||
result = slice[0]
|
||
for j := 1; j < len(slice); j++ {
|
||
result += "," + slice[j]
|
||
}
|
||
}
|
||
_ = result
|
||
}
|
||
|
||
runtime.GC()
|
||
runtime.ReadMemStats(&m2)
|
||
origAlloc := m2.TotalAlloc - m1.TotalAlloc
|
||
|
||
// 测试优化方法
|
||
runtime.GC()
|
||
runtime.ReadMemStats(&m1)
|
||
|
||
for i := 0; i < 1000; i++ {
|
||
result := JoinStrings(slice, ",")
|
||
_ = result
|
||
}
|
||
|
||
runtime.GC()
|
||
runtime.ReadMemStats(&m2)
|
||
optAlloc := m2.TotalAlloc - m1.TotalAlloc
|
||
|
||
t.Logf("原始方法内存分配: %d bytes", origAlloc)
|
||
t.Logf("优化方法内存分配: %d bytes", optAlloc)
|
||
t.Logf("内存减少: %.2f%%", float64(origAlloc-optAlloc)/float64(origAlloc)*100)
|
||
})
|
||
}
|
||
|
||
// TestPoolReuse 测试对象池复用效果(StringBuilderPool)
|
||
func TestPoolReuse(t *testing.T) {
|
||
// 重置计数器
|
||
pool := NewStringBuilderPool(1024)
|
||
|
||
// 执行多次操作
|
||
slice := []string{"a", "b", "c", "d", "e"}
|
||
for i := 0; i < 100; i++ {
|
||
result := pool.JoinStrings(slice, ",")
|
||
_ = result
|
||
}
|
||
|
||
// GetReusedCount 方法已移除,无法测试复用次数
|
||
t.Log("字符串构建器池测试完成")
|
||
|
||
// 切片池相关功能已移除,跳过该测试
|
||
t.Log("切片池功能已移除")
|
||
}
|
||
|
||
// TestStringBuilderCorrectness 测试字符串构建器正确性
|
||
func TestStringBuilderCorrectness(t *testing.T) {
|
||
testCases := []struct {
|
||
slice []string
|
||
sep string
|
||
want string
|
||
}{
|
||
{[]string{}, ",", ""},
|
||
{[]string{"a"}, ",", "a"},
|
||
{[]string{"a", "b"}, ",", "a,b"},
|
||
{[]string{"hello", "world", "test"}, " ", "hello world test"},
|
||
{[]string{"1", "2", "3", "4", "5"}, "-", "1-2-3-4-5"},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
got := JoinStrings(tc.slice, tc.sep)
|
||
want := strings.Join(tc.slice, tc.sep)
|
||
|
||
if got != want {
|
||
t.Errorf("JoinStrings(%v, %q) = %q, want %q", tc.slice, tc.sep, got, want)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestIntJoinCorrectness 测试整数连接正确性
|
||
func TestIntJoinCorrectness(t *testing.T) {
|
||
testCases := []struct {
|
||
slice []int
|
||
sep string
|
||
want string
|
||
}{
|
||
{[]int{}, ",", ""},
|
||
{[]int{1}, ",", "1"},
|
||
{[]int{1, 2}, ",", "1,2"},
|
||
{[]int{10, 20, 30}, "-", "10-20-30"},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
got := JoinInts(tc.slice, tc.sep)
|
||
|
||
if got != tc.want {
|
||
t.Errorf("JoinInts(%v, %q) = %q, want %q", tc.slice, tc.sep, got, tc.want)
|
||
}
|
||
}
|
||
}
|
||
|
||
// BenchmarkCredentialGeneration 模拟SSH凭证生成的性能测试
|
||
func BenchmarkCredentialGeneration(b *testing.B) {
|
||
users := []string{"admin", "root", "user", "test", "guest"}
|
||
passwords := make([]string, 20)
|
||
for i := range passwords {
|
||
passwords[i] = fmt.Sprintf("password%d", i)
|
||
}
|
||
|
||
b.ResetTimer()
|
||
for i := 0; i < b.N; i++ {
|
||
// 模拟SSH凭证生成过程
|
||
totalCreds := len(users) * len(passwords)
|
||
credentials := make([]struct{ user, pass string }, 0, totalCreds)
|
||
|
||
for _, user := range users {
|
||
for _, pass := range passwords {
|
||
credentials = append(credentials, struct{ user, pass string }{user, pass})
|
||
}
|
||
}
|
||
_ = credentials
|
||
}
|
||
}
|
||
|
||
// Example 展示如何使用优化后的工具
|
||
func ExampleJoinStrings() {
|
||
slice := []string{"apple", "banana", "cherry"}
|
||
result := JoinStrings(slice, ", ")
|
||
fmt.Println(result)
|
||
// Output: apple, banana, cherry
|
||
}
|
||
|
||
func ExampleJoinInts() {
|
||
ports := []int{80, 443, 8080, 9090}
|
||
result := JoinInts(ports, ",")
|
||
fmt.Println(result)
|
||
// Output: 80,443,8080,9090
|
||
}
|
||
|
||
// 运行时长度测试 - 验证在不同规模下的表现
|
||
func TestScalability(t *testing.T) {
|
||
sizes := []int{10, 100, 1000, 5000}
|
||
|
||
for _, size := range sizes {
|
||
t.Run(fmt.Sprintf("Size%d", size), func(t *testing.T) {
|
||
// 准备数据
|
||
slice := make([]string, size)
|
||
for i := range slice {
|
||
slice[i] = fmt.Sprintf("item-%d", i)
|
||
}
|
||
|
||
start := time.Now()
|
||
result := JoinStrings(slice, ",")
|
||
duration := time.Since(start)
|
||
|
||
t.Logf("规模 %d: 耗时 %v, 结果长度 %d", size, duration, len(result))
|
||
|
||
// 验证结果正确性(只检查开头和结尾)
|
||
expected := strings.Join(slice, ",")
|
||
if result != expected {
|
||
t.Errorf("结果不匹配")
|
||
}
|
||
})
|
||
}
|
||
} |