Сообщение Re[11]: секунда WTF (lock) от 28.01.2017 16:47
Изменено 28.01.2017 16:48 Mystic Artifact
Re[11]: секунда WTF (lock)
Здравствуйте, Sinix, Вы писали:
F>> PS: А Dictionary — зачем там?
S>http://stackoverflow.com/questions/3366376/are-net-switch-statements-hashed-or-indexed
Понял. То ли не знал, то ли забыл... Но рослин так не делает. Вместо этого он считает хэш строки, и генерирует код который сравнивает хэши. Начинает так делать он только если есть как минимум 7 кейсов.
Ну т.е. для:
Он генерирует:
Где ComputeStringHash:
К сожалению ilspy не хочет видеть PrivateImplementationDetails.
F>> PS: А Dictionary — зачем там?
S>http://stackoverflow.com/questions/3366376/are-net-switch-statements-hashed-or-indexed
Понял. То ли не знал, то ли забыл... Но рослин так не делает. Вместо этого он считает хэш строки, и генерирует код который сравнивает хэши. Начинает так делать он только если есть как минимум 7 кейсов.
Ну т.е. для:
public static int Main(string[] args)
{
switch (args[0])
{
case "s1": return 1;
case "s2": return 2;
case "s3": return 3;
case "s4": return 4;
case "s5": return 5;
case "s6": return 6;
case "s7": return 7;
}
return 0;
}
Он генерирует:
public static int Main(string[] args)
{
string text = args[0];
uint num = <PrivateImplementationDetails>.ComputeStringHash(text);
if (num <= 139573449u)
{
if (num != 89240592u)
{
if (num != 106018211u)
{
if (num == 139573449u)
{
if (text == "s1")
{
return 1;
}
}
}
else if (text == "s3")
{
return 3;
}
}
else if (text == "s2")
{
return 2;
}
}
else if (num <= 173128687u)
{
if (num != 156351068u)
{
if (num == 173128687u)
{
if (text == "s7")
{
return 7;
}
}
}
else if (text == "s6")
{
return 6;
}
}
else if (num != 189906306u)
{
if (num == 206683925u)
{
if (text == "s5")
{
return 5;
}
}
}
else if (text == "s4")
{
return 4;
}
return 0;
}
Где ComputeStringHash:
.method assembly hidebysig static
uint32 ComputeStringHash (
string s
) cil managed
{
// Method begins at RVA 0x21a8
// Code size 44 (0x2c)
.maxstack 2
.locals init (
[0] uint32,
[1] int32
)
IL_0000: ldarg.0
IL_0001: brfalse.s IL_002a
IL_0003: ldc.i4 -2128831035
IL_0008: stloc.0
IL_0009: ldc.i4.0
IL_000a: stloc.1
IL_000b: br.s IL_0021
// loop start (head: IL_0021)
IL_000d: ldarg.0
IL_000e: ldloc.1
IL_000f: callvirt instance char [mscorlib]System.String::get_Chars(int32)
IL_0014: ldloc.0
IL_0015: xor
IL_0016: ldc.i4 16777619
IL_001b: mul
IL_001c: stloc.0
IL_001d: ldloc.1
IL_001e: ldc.i4.1
IL_001f: add
IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: ldarg.0
IL_0023: callvirt instance int32 [mscorlib]System.String::get_Length()
IL_0028: blt.s IL_000d
// end loop
IL_002a: ldloc.0
IL_002b: ret
} // end of method '<PrivateImplementationDetails>'::ComputeStringHash
К сожалению ilspy не хочет видеть PrivateImplementationDetails.
Re[11]: секунда WTF (lock)
Здравствуйте, Sinix, Вы писали:
F>> PS: А Dictionary — зачем там?
S>http://stackoverflow.com/questions/3366376/are-net-switch-statements-hashed-or-indexed
Понял. То ли не знал, то ли забыл... Но рослин так не делает. Вместо этого он считает хэш строки, и генерирует код который сравнивает хэши. Начинает так делать он только если есть как минимум 7 кейсов.
Ну т.е. для:
Он генерирует:
Где ComputeStringHash:
К сожалению ilspy не хочет видеть PrivateImplementationDetails (при декомпиляции в C#).
F>> PS: А Dictionary — зачем там?
S>http://stackoverflow.com/questions/3366376/are-net-switch-statements-hashed-or-indexed
Понял. То ли не знал, то ли забыл... Но рослин так не делает. Вместо этого он считает хэш строки, и генерирует код который сравнивает хэши. Начинает так делать он только если есть как минимум 7 кейсов.
Ну т.е. для:
public static int Main(string[] args)
{
switch (args[0])
{
case "s1": return 1;
case "s2": return 2;
case "s3": return 3;
case "s4": return 4;
case "s5": return 5;
case "s6": return 6;
case "s7": return 7;
}
return 0;
}
Он генерирует:
public static int Main(string[] args)
{
string text = args[0];
uint num = <PrivateImplementationDetails>.ComputeStringHash(text);
if (num <= 139573449u)
{
if (num != 89240592u)
{
if (num != 106018211u)
{
if (num == 139573449u)
{
if (text == "s1")
{
return 1;
}
}
}
else if (text == "s3")
{
return 3;
}
}
else if (text == "s2")
{
return 2;
}
}
else if (num <= 173128687u)
{
if (num != 156351068u)
{
if (num == 173128687u)
{
if (text == "s7")
{
return 7;
}
}
}
else if (text == "s6")
{
return 6;
}
}
else if (num != 189906306u)
{
if (num == 206683925u)
{
if (text == "s5")
{
return 5;
}
}
}
else if (text == "s4")
{
return 4;
}
return 0;
}
Где ComputeStringHash:
.method assembly hidebysig static
uint32 ComputeStringHash (
string s
) cil managed
{
// Method begins at RVA 0x21a8
// Code size 44 (0x2c)
.maxstack 2
.locals init (
[0] uint32,
[1] int32
)
IL_0000: ldarg.0
IL_0001: brfalse.s IL_002a
IL_0003: ldc.i4 -2128831035
IL_0008: stloc.0
IL_0009: ldc.i4.0
IL_000a: stloc.1
IL_000b: br.s IL_0021
// loop start (head: IL_0021)
IL_000d: ldarg.0
IL_000e: ldloc.1
IL_000f: callvirt instance char [mscorlib]System.String::get_Chars(int32)
IL_0014: ldloc.0
IL_0015: xor
IL_0016: ldc.i4 16777619
IL_001b: mul
IL_001c: stloc.0
IL_001d: ldloc.1
IL_001e: ldc.i4.1
IL_001f: add
IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: ldarg.0
IL_0023: callvirt instance int32 [mscorlib]System.String::get_Length()
IL_0028: blt.s IL_000d
// end loop
IL_002a: ldloc.0
IL_002b: ret
} // end of method '<PrivateImplementationDetails>'::ComputeStringHash
К сожалению ilspy не хочет видеть PrivateImplementationDetails (при декомпиляции в C#).