{
	"schemaVersion": 1,
	"title": "Substring Search Benchmark Report",
	"description": "Synthetic large-catalog search benchmarks for the kind of item, tooltip, mod-name, and tag searching players use in recipe viewers.",
	"benchmarkClass": "net.mezzdev.substringsearch.benchmark.LargeCatalogSearchBenchmark",
	"project": {
		"groupId": "net.mezzdev",
		"artifactId": "substring-search-benchmarks",
		"version": "0.1.0-SNAPSHOT",
		"javaRelease": "25"
	},
	"toolchain": {
		"jmhVersion": "1.37",
		"scoreErrorConfidence": 0.95,
		"modDevGradleVersion": "2.0.141",
		"neoFormVersion": "26.2-2"
	},
	"itemCounts": [
		100000
	],
	"typedSearch": {
		"terms": [
			"reinforced copper ingot",
			"polished redstone nugget",
			"tempered sapphire ingot",
			"gilded topaz nugget",
			"raw steel ingot",
			"cut glass nugget",
			"smooth quartz ingot",
			"silent slate nugget",
			"Aster Works",
			"Beacon Works",
			"Cinder Works",
			"Delta Works",
			"bench:ingots/copper_ingot",
			"bench:tools/copper_ingot",
			"stat 0 detail",
			"dense nickel ingot"
		],
		"typedCharacterCounts": [
			1,
			2,
			3,
			4,
			5,
			6,
			7,
			8,
			9,
			10,
			11
		],
		"queriesByLength": {
			"1": [
				"r",
				"p",
				"t",
				"g",
				"r",
				"c",
				"s",
				"s",
				"A",
				"B",
				"C",
				"D",
				"b",
				"b",
				"s",
				"d"
			],
			"2": [
				"re",
				"po",
				"te",
				"gi",
				"ra",
				"cu",
				"sm",
				"si",
				"As",
				"Be",
				"Ci",
				"De",
				"be",
				"be",
				"st",
				"de"
			],
			"3": [
				"rei",
				"pol",
				"tem",
				"gil",
				"raw",
				"cut",
				"smo",
				"sil",
				"Ast",
				"Bea",
				"Cin",
				"Del",
				"ben",
				"ben",
				"sta",
				"den"
			],
			"4": [
				"rein",
				"poli",
				"temp",
				"gild",
				"raw ",
				"cut ",
				"smoo",
				"sile",
				"Aste",
				"Beac",
				"Cind",
				"Delt",
				"benc",
				"benc",
				"stat",
				"dens"
			],
			"5": [
				"reinf",
				"polis",
				"tempe",
				"gilde",
				"raw s",
				"cut g",
				"smoot",
				"silen",
				"Aster",
				"Beaco",
				"Cinde",
				"Delta",
				"bench",
				"bench",
				"stat ",
				"dense"
			],
			"6": [
				"reinfo",
				"polish",
				"temper",
				"gilded",
				"raw st",
				"cut gl",
				"smooth",
				"silent",
				"Aster ",
				"Beacon",
				"Cinder",
				"Delta ",
				"bench:",
				"bench:",
				"stat 0",
				"dense "
			],
			"7": [
				"reinfor",
				"polishe",
				"tempere",
				"gilded ",
				"raw ste",
				"cut gla",
				"smooth ",
				"silent ",
				"Aster W",
				"Beacon ",
				"Cinder ",
				"Delta W",
				"bench:i",
				"bench:t",
				"stat 0 ",
				"dense n"
			],
			"8": [
				"reinforc",
				"polished",
				"tempered",
				"gilded t",
				"raw stee",
				"cut glas",
				"smooth q",
				"silent s",
				"Aster Wo",
				"Beacon W",
				"Cinder W",
				"Delta Wo",
				"bench:in",
				"bench:to",
				"stat 0 d",
				"dense ni"
			],
			"9": [
				"reinforce",
				"polished ",
				"tempered ",
				"gilded to",
				"raw steel",
				"cut glass",
				"smooth qu",
				"silent sl",
				"Aster Wor",
				"Beacon Wo",
				"Cinder Wo",
				"Delta Wor",
				"bench:ing",
				"bench:too",
				"stat 0 de",
				"dense nic"
			],
			"10": [
				"reinforced",
				"polished r",
				"tempered s",
				"gilded top",
				"raw steel ",
				"cut glass ",
				"smooth qua",
				"silent sla",
				"Aster Work",
				"Beacon Wor",
				"Cinder Wor",
				"Delta Work",
				"bench:ingo",
				"bench:tool",
				"stat 0 det",
				"dense nick"
			],
			"11": [
				"reinforced ",
				"polished re",
				"tempered sa",
				"gilded topa",
				"raw steel i",
				"cut glass n",
				"smooth quar",
				"silent slat",
				"Aster Works",
				"Beacon Work",
				"Cinder Work",
				"Delta Works",
				"bench:ingot",
				"bench:tools",
				"stat 0 deta",
				"dense nicke"
			]
		}
	},
	"reportSections": [
		{
			"id": "build-time",
			"name": "Build Time Rankings",
			"metric": "startup or reload time spent preparing search",
			"unit": "ms/build",
			"lowerIsBetter": true,
			"description": "Measures how long it takes to prepare the search index after a large item list is available. Lower values mean a recipe viewer can become searchable sooner after game startup, resource reloads, or data reloads.",
			"benchmarkGroups": [
				"build"
			]
		},
		{
			"id": "typed-search-time",
			"name": "Typed Search Time",
			"metric": "time to process one search-box update",
			"unit": "ms/query",
			"lowerIsBetter": true,
			"description": "Measures the cost of one search-box update as a player types more characters. Lower values mean less input lag while filtering a very large item list.",
			"benchmarkGroups": [
				"typed-search"
			]
		},
		{
			"id": "allocation-100k",
			"name": "Allocation Rankings At 100k",
			"metric": "temporary garbage created while preparing search",
			"unit": "bytes/build",
			"lowerIsBetter": true,
			"description": "Measures temporary objects allocated while building the index for a 100,000-item catalog. Lower values reduce GC pressure and the chance of startup or reload stutter.",
			"benchmarkGroups": [
				"build"
			]
		},
		{
			"id": "typed-allocation-100k",
			"name": "Typed Search Allocations At 100k",
			"metric": "temporary garbage created per search-box update",
			"unit": "bytes/query",
			"lowerIsBetter": true,
			"description": "Measures temporary objects allocated for each search-box update against a 100,000-item catalog. Lower values reduce GC pressure while a player is typing.",
			"benchmarkGroups": [
				"typed-search"
			]
		},
		{
			"id": "retained-memory",
			"name": "Retained Memory",
			"metric": "RAM kept by the ready-to-use search index",
			"unit": "bytes",
			"lowerIsBetter": true,
			"description": "Estimates how much heap the completed all-defaults search index keeps after loading. Lower values leave more memory for the rest of the game and modpack.",
			"benchmarkGroups": [
				"retained-memory"
			]
		}
	],
	"implementations": [
		{
			"id": "generalized-suffix-tree",
			"name": "Suffix tree",
			"authors": "Abahgat, mezz",
			"version": "1.3.0",
			"source": "pkg:maven/net.mezzdev:suffixtree@1.3.0",
			"sourceUrl": "https://github.com/mezz/generalized-suffix-tree",
			"note": "",
			"order": 0
		},
		{
			"id": "abahgat-suffix-tree",
			"name": "Suffix tree",
			"authors": "Abahgat",
			"version": "2.0.0",
			"source": "pkg:maven/com.abahgat:suffixtree@2.0.0",
			"sourceUrl": "https://github.com/abahgat/suffixtree",
			"note": "",
			"order": 1
		},
		{
			"id": "baked-substring-index",
			"name": "Baked substring index",
			"authors": "mezz",
			"version": "0.1.0",
			"source": "pkg:maven/net.mezzdev:baked-substring-index@0.1.0",
			"sourceUrl": "https://github.com/mezz/baked-substring-index",
			"note": "",
			"order": 2
		},
		{
			"id": "baked-suffix-array-index",
			"name": "Baked suffix array index",
			"authors": "mezz",
			"version": "0.1.0",
			"source": "pkg:maven/net.mezzdev:baked-suffix-array-index@0.1.0",
			"sourceUrl": "https://github.com/mezz/baked-suffix-array-index",
			"note": "",
			"order": 3
		},
		{
			"id": "minecraft-suffix-array",
			"name": "Suffix array",
			"authors": "Minecraft",
			"version": "1.12-pre6 to 26.2",
			"source": "Minecraft 1.12-pre6 to 26.2 SuffixArray via NeoForm 26.2-2",
			"sourceUrl": "https://github.com/neoforged/NeoForm",
			"note": "Benchmark uses net.minecraft.client.searchtree.SuffixArray from NeoForm 26.2-2. A manual all-versions binary search found the SuffixArray bytecode signature from Minecraft 1.12-pre6 through 26.2; the first release with the signature is 1.12.",
			"order": 4
		}
	],
	"benchmarks": [
		{
			"id": "buildAllDefaultsIndex",
			"name": "Build: All Defaults",
			"description": "Prepares the full default search index: item names, tooltip text, mod names, and tags. This is the closest benchmark to the total search setup cost players feel after loading or reloading a large modpack.",
			"group": "build",
			"order": 10,
			"legacy": false
		},
		{
			"id": "buildItemNamesIndex",
			"name": "Build: Item Names",
			"description": "Prepares search for the item names players see in the item list. This is the basic name-search part of startup or reload cost.",
			"group": "build",
			"order": 20,
			"legacy": false
		},
		{
			"id": "buildTooltipLinesIndex",
			"name": "Build: Tooltip Lines",
			"description": "Prepares search for tooltip text such as hold-Shift details, stats, and descriptions. Tooltip text is large and repetitive, so it can dominate startup time, temporary garbage, and memory.",
			"group": "build",
			"order": 30,
			"legacy": false
		},
		{
			"id": "buildModNamesIndex",
			"name": "Build: Mod Names",
			"description": "Prepares search for the mod or source name shown for each item. This corpus is smaller than tooltips, but it shows the fixed cost of supporting mod-name searches.",
			"group": "build",
			"order": 40,
			"legacy": false
		},
		{
			"id": "buildTagsIndex",
			"name": "Build: Tags",
			"description": "Prepares search for tag-style strings players use to find item groups such as ingots, ores, or storage blocks. More indexed text means more startup work and memory.",
			"group": "build",
			"order": 50,
			"legacy": false
		},
		{
			"id": "searchAllDefaultsTypedCatalogPrefix",
			"name": "Typed Search: Default Corpus Prefix",
			"description": "Simulates a player typing in the search box after the index is ready. Each step searches prefixes from many item-like words, so lower values mean the filtered item list updates with less typing lag.",
			"group": "typed-search",
			"order": 200,
			"legacy": false
		},
		{
			"id": "retainedApproxAllDefaultsIndexBytes",
			"name": "Retained Memory: All Defaults",
			"description": "Keeps the full default search index alive and estimates the heap it occupies after loading. Lower values mean the search feature leaves more RAM for the game, resource packs, and other mods. This retained-memory number is approximate.",
			"group": "retained-memory",
			"order": 300,
			"legacy": false
		}
	]
}
