Senior Member
|
07-29-2010
, 10:49
weapon string to index
|
#1
|
Is this what you call "expensive", if called everytime a bullet is fired ingame... ?
PHP Code:
#pragma semicolon 1
#include <sourcemod> #include <sdktools> #include <profiler>
#define PLUGIN_VERSION "1.1c" new String: weaponlist[][] = { "ak47", "m4a1", "awp", "deagle", "mp5navy", "aug", "p90", "famas", "galil", "scout", "g3sg1", "hegrenade", "usp", "glock", "m249", "m3", "elite", "fiveseven", "mac10", "p228", "sg550", "sg552", "tmp", "ump45", "xm1014", "knife" }; new hashlist[] = { 322, 312, 328, 610, 725, 317, 226, 520, 521, 558, 425, 931, 344, 528, 283, 163, 531, 971, 403, 280, 382, 386, 337, 452, 433, 525 }; //hashlist is generated by adding up all ascii chars PLUS the numeric value of each char if they are numeric //e.g. m3 = 109+51+3 //this will certainly not work on much strings, but does not generate any collisions on this short weapon list
get_weapon_hash(const String: weapon_name[]) { new hash, WPlen = strlen(weapon_name); for(new I = 0;I < WPlen;I++) { decl String:inmid[2]; strcopy(inmid,2,weapon_name[i]); //new char:inmid = weapon_name[i]; hash += inmid[0]; if(IsCharNumeric(inmid[0])) hash += StringToInt(inmid); } new loop_break = 0, index = 0, hWPsize = sizeof(hashlist); while ((loop_break == 0) && (index < hWPsize)) { if (hash == hashlist[index]) loop_break++; index++; }
if (loop_break == 0) return -1; else return index - 1; }
get_weapon_index(const String: weapon_name[]) { new loop_break = 0, index = 0, sWPsize = sizeof(weaponlist); while ((loop_break == 0) && (index < sWPsize)) { if (strcmp(weapon_name, weaponlist[index], true) == 0) loop_break++; index++; }
if (loop_break == 0) return -1; else return index - 1; }
public Plugin:myinfo = { name = "stringtest", author = "Timiditas", description = "string hashing", version = PLUGIN_VERSION, url = "nowhere to run" };
public OnPluginStart() { RegConsoleCmd("hash", fhash); RegConsoleCmd("find", find); }
public Action:fhash(client, args) { if (args != 1) { ReplyToCommand(client, "usage: hash <anystring>"); return Plugin_Handled; } decl String:argument[255]; GetCmdArg(1, argument, 255); new Handle:myProf = CreateProfiler(); decl IDX; StartProfiling(myProf); IDX = get_weapon_hash(argument); StopProfiling(myProf); new Float:TheTime = GetProfilerTime(myProf); CloseHandle(myProf); ReplyToCommand(client, "Returned index: %i, HPT needed in seconds: %f",IDX,TheTime); return Plugin_Handled; }
public Action:find(client, args) { if (args != 1) { ReplyToCommand(client, "usage: find <anystring>"); return Plugin_Handled; } decl String:argument[255]; GetCmdArg(1, argument, 255); new Handle:myProf = CreateProfiler(); decl IDX; StartProfiling(myProf); IDX = get_weapon_index(argument); StopProfiling(myProf); new Float:TheTime = GetProfilerTime(myProf); CloseHandle(myProf); ReplyToCommand(client, "Returned index: %i, HPT needed in seconds: %f",IDX,TheTime); return Plugin_Handled; }
Performance results below:
Code:
] find ak47
Returned index: 0, HPT needed in seconds: 0.000001
] hash ak47
Returned index: 0, HPT needed in seconds: 0.000003
] find knife
Returned index: 25, HPT needed in seconds: 0.000002
] hash knife
Returned index: 25, HPT needed in seconds: 0.000003
] find m3
Returned index: 15, HPT needed in seconds: 0.000002
] hash m3
Returned index: 15, HPT needed in seconds: 0.000003
] find fiveseven
Returned index: 17, HPT needed in seconds: 0.000002
] hash fiveseven
Returned index: 17, HPT needed in seconds: 0.000003
] find UNKNOWNSTRING
Returned index: -1, HPT needed in seconds: 0.000002
] hash UNKNOWNSTRING
Returned index: -1, HPT needed in seconds: 0.000004
So simply comparing the INTs is faster of course, but the required hashing at the beginning of get_weapon_hash() makes it slower.
~~edit
Actually, if you pack it into two loops, the results differ significantly.
PHP Code:
public Action:fhash(client, args) { if (args != 1) { ReplyToCommand(client, "usage: hash <anystring>"); return Plugin_Handled; } decl String:argument[255]; GetCmdArg(1, argument, 255); new Handle:myProf = CreateProfiler(); decl IDX, Float:Times; for(new j = 1;j<1001;j++) { StartProfiling(myProf); for(new i = 1;i<1001;i++) { IDX = get_weapon_hash(argument); } StopProfiling(myProf); Times += GetProfilerTime(myProf); } Times /= 1000.0; CloseHandle(myProf); ReplyToCommand(client, "Returned index: %i, HPT needed in seconds: %f",IDX,Times); return Plugin_Handled; }
public Action:find(client, args) { if (args != 1) { ReplyToCommand(client, "usage: find <anystring>"); return Plugin_Handled; } decl String:argument[255]; GetCmdArg(1, argument, 255); new Handle:myProf = CreateProfiler(); decl IDX, Float:Times; for(new j = 1;j<1001;j++) { StartProfiling(myProf); for(new i = 1;i<1001;i++) { IDX = get_weapon_index(argument); } StopProfiling(myProf); Times += GetProfilerTime(myProf); } Times /= 1000.0; CloseHandle(myProf); ReplyToCommand(client, "Returned index: %i, HPT needed in seconds: %f",IDX,Times); return Plugin_Handled; }
Results:
Code:
] find no
Returned index: -1, HPT needed in seconds: 0.001577
] hash no
Returned index: -1, HPT needed in seconds: 0.000444
] find no
Returned index: -1, HPT needed in seconds: 0.001581
] hash no
Returned index: -1, HPT needed in seconds: 0.000444
] find ak47
Returned index: 0, HPT needed in seconds: 0.000078
] hash ak47
Returned index: 0, HPT needed in seconds: 0.000750
] find knife
Returned index: 25, HPT needed in seconds: 0.001606
] hash knife
Returned index: 25, HPT needed in seconds: 0.000791
] find UNKNOWNSTRING
Returned index: -1, HPT needed in seconds: 0.001584
] hash UNKNOWNSTRING
Returned index: -1, HPT needed in seconds: 0.001692
] find m3
Returned index: 15, HPT needed in seconds: 0.001077
] hash m3
Returned index: 15, HPT needed in seconds: 0.000498
] find glock
Returned index: 13, HPT needed in seconds: 0.000948
] hash glock
Returned index: 13, HPT needed in seconds: 0.000729
] find hegrenade
Returned index: 11, HPT needed in seconds: 0.000764
] hash hegrenade
Returned index: 11, HPT needed in seconds: 0.001162
] find g3sg1
Returned index: 10, HPT needed in seconds: 0.000728
] hash g3sg1
Returned index: 10, HPT needed in seconds: 0.000960
The wiki says:
Quote:
The compiler, in fact, is very poor at optimizing
|
I wonder how much of the 'poor' optimizations kick in in the above loops.
__________________
Last edited by Timiditas; 07-29-2010 at 12:24.
Reason: extended code to fully functional plugin
|
|