Quote:
Originally Posted by AndreT
Function time complexity is not associated with the actual time it may take for it to execute as this may greatly vary from system to system. Instead it represents the number of operations performed.
The complexity of map::find is O(log n) - that is very efficient and comes from how maps operate internally using binary search.
Anyways this is a very elegant solution in terms of code readability and file organizing, but lets not get ourselves too deep into the premature optimization, shall we :P
|
I'm working on a library for SampGDK which will provide ZCMD:command , just like in PAWN.
Edit: I made some progress.. this is what I currently have made:
pawn Код:
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#define PLUGIN_EXPORT
#define PLUGIN_CALL
//begin command library
//header
class Command
{
public:
virtual bool do_command(int playerid, std::string params) = 0;
};
#define CMD(name) \
class cmd ## name : public Command\
{\
public:\
cmd ## name() { ZCMD_COMMAND_LIBRARY_register_command(this, "/"#name); }\
bool do_command(int playerid, std::string params)
//M$ and clang have a mangled name limit of 2048 chars, g++ "unlimited" (well, limited by memory).
#define CMDEND(name) };cmd ## name ZCMD_COMMAND_LIBRARY_CMD_ ## name;
bool OnPlayerCommandReceived(int playerid,std::string command, std::string params);
void OnPlayerCommandExecuted(int playerid, std::string, std::string params, bool success);
//source
std::map<std::string, Command*> ZCMD_COMMAND_LIBRARY_command_map;
void ZCMD_COMMAND_LIBRARY_register_command(Command* cmd, std::string name)
{
std::string data(name);
std::transform(data.begin(), data.end(), data.begin(), ::tolower);
ZCMD_COMMAND_LIBRARY_command_map[data] = cmd;
}
PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerCommandText(int playerid, const char *cmdtext)
{
std::string main(cmdtext);
std::string command;
std::string parameters;
size_t space = main.find(' ');
if(space == std::string::npos)
{
command.assign(main);
}
else
{
command.assign(main.begin(),main.begin()+space);
parameters.assign(main.begin()+(space+1),main.end());
}
std::transform(command.begin(), command.end(), command.begin(), ::tolower);
if(OnPlayerCommandReceived(playerid,command,parameters))
{
if(ZCMD_COMMAND_LIBRARY_command_map.find(command) != ZCMD_COMMAND_LIBRARY_command_map.end())
{
bool success = ZCMD_COMMAND_LIBRARY_command_map[command]->do_command(playerid,parameters);
OnPlayerCommandExecuted(playerid, command, parameters, success);
return success;
}
}
else
{
return false;
}
//printf("Unknown command: %s\n",command.c_str());
return false;
}
//end command library
//end-user code
bool OnPlayerCommandReceived(int playerid,std::string command, std::string params)
{
return true;
}
void OnPlayerCommandExecuted(int playerid, std::string command, std::string params, bool success)
{
return;
}
CMD(start)
{
//printf("start issued, params: '%s'\n",params.c_str());
return true;
}
CMDEND(start);
CMD(end)
{
//printf("end issued, params: '%s'\n",params.c_str());
return false;
}
CMDEND(end);
//end commands
//test run
#include <Windows.h>
int main()
{
DWORD end;
DWORD time = GetTickCount();
for(int i =0; i < 1000000; ++i)
{
OnPlayerCommandText(0, "/start");
OnPlayerCommandText(0, "/StaRT");
OnPlayerCommandText(0, "/start ello lololol");
OnPlayerCommandText(0, "/kill");
OnPlayerCommandText(0, "/end");
OnPlayerCommandText(0, "/end 1234");
}
end = GetTickCount();
printf("%d ms\n",end-time);
return 0;
}
it takes 2 seconds to execute on my machine. That means it can process a total of around 500,000 commands in one second.
Edit2:
Done:
https://sampforum.blast.hk/showthread.php?tid=436322