[Include] FoxForeach Fast and simple player loop
#7

Quote:
Originally Posted by Yashas
Посмотреть сообщение
Your speed test is flawed.


All the foreach includes are going to have the same speed while looping since they use the same idea. The only faster foreach can be made using native calls to plugin.

Код:
native SLE_algo_foreach_list_init(list:listid, &val);
native SLE_algo_foreach_list_get(feid);

#define foreach::list(%0(%1)) for(new %1, fel_%0@%1_id = SLE_algo_foreach_list_init(%0, %1); SLE_algo_foreach_list_get(fel_%0@%1_id);)
Код:
class ForeachList
{
public:
	ForeachList(AMX * amx, cell * counter, std::list<cell>::const_iterator itr, std::list<cell>::const_iterator end) : amx(amx), counter(counter), itr(itr), end(end)
	{}
.
.
.
.
	inline cell iterate()
	{
		bool cond = itr != end;
		if (cond)
		{
			*counter = *itr++;
		}
		return cond;
	}
	AMX * amx;
	cell * counter;
	std::list<cell>::const_iterator itr;
	std::list<cell>::const_iterator end;
};

cell AMX_NATIVE_CALL SLE_algo_foreach_list_init(AMX* amx, cell* params)
{
	unsigned int id = -1;
	if (IsValidListID(static_cast<int>(params[1])))
	{		
		cell* addr = NULL;
		amx_GetAddr(amx, params[2], &addr);
		if (unused_foreach_list_ids.size())
		{
			id = unused_foreach_list_ids.back();
			unused_foreach_list_ids.pop_back();
		}
		else
		{
			id = foreach_list_loop_maxid = active_foreach_list_loops.size();
			active_foreach_list_loops.push_back(nullptr);
		}
		active_foreach_list_loops[id] = new ForeachList(amx, addr, active_lists[static_cast<int>(params[1])]->container->cbegin(), active_lists[static_cast<int>(params[1])]->container->cend());
	}
	return id;
}
cell AMX_NATIVE_CALL SLE_algo_foreach_list_get(AMX* amx, cell* params)
{
	// Assuming that people don't try to screw with these internal functions
	// As long as the foreach define makes this call, it shall always be valid.
	// TO:CHECK If iterator remains valid when nodes are removed/added to the list while the foreach is running
	int foreachid = static_cast<int>(params[1]);
	if (foreachid > static_cast<int>(foreach_list_loop_maxid) || foreachid < 0) return 0;
	return active_foreach_list_loops[foreachid]->iterate();
}
That makes calls to a plugin which returns the data. Its faster because making function calls are slightly faster than dereferencing arrays and the rest of the work of returning the correct value is done within a plugin which hardly takes any time.

This idea wont work in PAWN because you are going to de-reference an array after calling the function which is slow whereas in my case the hard work was done by the plugin and you know that plugin can do things amazingly fast.

Areas where you can look for improvements are:
  • Insertion
  • Deletion
Maybe use a sorted array? I haven't tried and I don't know if you will gain an overall significant improvement in performance.
The test is flawed okay, but why foreach caused a server crash, when FoxForeach work further.
In this case, my solution for someone who is not interested in adding the plugin, you'll probably better.
Reply


Messages In This Thread
FoxForeach Fast and simple player loop - by AbyssMorgan - 03.07.2016, 05:51
Re: FoxForeach Fast and simple player loop - by Gammix - 03.07.2016, 06:27
Re: FoxForeach Fast and simple player loop - by AbyssMorgan - 03.07.2016, 06:30
Re: FoxForeach Fast and simple player loop - by SyS - 03.07.2016, 06:31
Re: FoxForeach Fast and simple player loop - by AbyssMorgan - 03.07.2016, 06:33
Re: FoxForeach Fast and simple player loop - by Yashas - 06.07.2016, 14:07
Re: FoxForeach Fast and simple player loop - by AbyssMorgan - 06.07.2016, 14:16
Re: FoxForeach Fast and simple player loop - by AbyssMorgan - 06.07.2016, 18:06

Forum Jump:


Users browsing this thread: 1 Guest(s)