Optimize UniHumanoid.BoneLimit.ToHumanBoneName

This change optimizes the following points:

(1) Replace linear search for "cashedHumanTraitBoneName" with Dictionary.
(2) Avoid GC alloc in the inner loop.
(2a) Do b.ToString() at the outside of the loop.
(2b) Do x.Replace(" ", "") at once in the static constructor of BoneLimit.
This commit is contained in:
Takayuki Matsuoka 2022-09-07 16:56:46 +09:00
parent da04ce7379
commit aac707d187

View File

@ -20,6 +20,19 @@ namespace UniHumanoid
public Vector3 center;
public float axisLength;
private static string[] cashedHumanTraitBoneName = null;
private static readonly Dictionary<HumanBodyBones, string> cachedHumanBodyBonesToBoneNameMap =
new Dictionary<HumanBodyBones, string>();
static BoneLimit()
{
// 呼び出し毎にGCが発生するのでキャッシュする
string[] boneNames = HumanTrait.BoneName;
cashedHumanTraitBoneName = new string[boneNames.Length];
for (var i = 0; i < boneNames.Length; i++)
{
cashedHumanTraitBoneName[i] = boneNames[i].Replace(" ", "");
}
}
public static BoneLimit From(HumanBone bone)
{
@ -37,16 +50,17 @@ namespace UniHumanoid
public static String ToHumanBoneName(HumanBodyBones b)
{
// 呼び出し毎にGCが発生するのでキャッシュする
if (cashedHumanTraitBoneName == null)
if (cachedHumanBodyBonesToBoneNameMap.TryGetValue(b, out string result))
{
cashedHumanTraitBoneName = HumanTrait.BoneName;
return result;
}
var bs = b.ToString();
foreach (var x in cashedHumanTraitBoneName)
{
if (x.Replace(" ", "") == b.ToString())
if (x == bs)
{
cachedHumanBodyBonesToBoneNameMap[b] = x;
return x;
}
}