A little [release] for std::map...
#1

As I was having issues compiling a very large project with pawno (for an upcoming server), (taking over 10 minutes to compile a 75k~ loc script on a 4.8 ghz, 8c, 24 gb memory computer).I had to wait over 10 minutes when making small modifications. I decided it was time to convert the script to C++. (Now takes 1 second to compile in visual studio).

I ended up using std::map a lot. After a few long days of work, there's still around 6k loc to convert. And I've made a big mistake.

Код:
Players[playerid].AddTextToInfoBox(StringBuffer);
Players[playerid].GenerateSpawnLocation();		
SetSpawnInfo(playerid, 0, Players[playerid].Skin, Players[playerid].Spawn_X, Players[playerid].Spawn_Y, Players[playerid].Spawn_Z, Players[playerid].Spawn_Angle, 0, 0, 0, 0, 0, 0);
TogglePlayerSpectating(playerid, false);
Players[playerid].UpdateQuest_Login();
Instead of using an iterator/pointer pointing to the player to read/write data, I've used operator[] for all the script. Not only for players, but for everything else. It doesn't look like an issue, but when you have 800 players online, you might not see it but it slows everything down by 24x on a single-threaded 4.8ghz. It's not an issue with a fast server. But still, it's better to fix it then deal with it in the future. Reason it slows down is because operator[] runs a search each time, and doesn't cache the old key. Even if you use the same key one after another, it still runs the search.

So instead of rewriting my whole code to use pointers and iterators to the data, I decided to create a cached map class and replace std::map by std::map_cache..Now my code is 24x faster. For those who have made the same mistake as I did, here's the map_cache class. It's very basic stuff, and at the same time, very helpful. It's missing a lot of functions, I've only added the functions I needed. You can easily add them though.

map_cache.h
Код:
#ifndef MAPCACHE_H
#define MAPCACHE_H
#pragma once

#include <map>

namespace std
{
	template<class _Kty, class _Ty,
		class _Pr = less<_Kty>,
		class _Alloc = allocator<pair<const _Kty, _Ty>>>
		class map_cache
	{

	public:

		typedef map<_Kty, _Ty, _Pr, _Alloc> _Myt;
		typedef _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> > _Mybase;
		typedef _Kty key_type;
		typedef _Ty mapped_type;
		typedef _Pr key_compare;
		typedef typename _Mybase::value_compare value_compare;
		typedef typename _Mybase::allocator_type allocator_type;
		typedef typename _Mybase::size_type size_type;
		typedef typename _Mybase::difference_type difference_type;
		typedef typename _Mybase::pointer pointer;
		typedef typename _Mybase::const_pointer const_pointer;
		typedef typename _Mybase::reference reference;
		typedef typename _Mybase::const_reference const_reference;
		typedef typename _Mybase::iterator iterator;
		typedef typename _Mybase::const_iterator const_iterator;
		typedef typename _Mybase::reverse_iterator reverse_iterator;
		typedef typename _Mybase::const_reverse_iterator
			const_reverse_iterator;
		typedef typename _Mybase::value_type value_type;

		typedef typename _Mybase::_Alty _Alty;
		typedef typename _Mybase::_Pairib _Pairib;

		map_cache()
		{
			first = true;
		}

		iterator begin()
		{
			return data.begin();
		}

		iterator end()
		{
			return data.end();
		}

		bool empty()
		{
			return data.empty();
		}

		iterator find(_Kty key)
		{
			return data.find(key);
		}

		unsigned int erase(_Kty key)
		{
			first = true;
			return data.erase(key);
		}

		iterator erase(iterator key)
		{
			first = true;
			return data.erase(key);
		}

		size_type size()
		{
			return data.size();
		}

		void clear()
		{
			first = true;
			data.clear();
		}

		_Ty& operator[](_Kty key)
		{
			if (first)
			{
				lastkey = key;
				lastval = &data.operator[](key);
				first = false;
				return *lastval;
			}
			if (lastkey == key)
			{
				return *lastval;
			}
			lastkey = key;
			lastval = &data.operator[](key);
			return *lastval;
		}

		std::map<_Kty, _Ty> data;

	private:

		_Kty lastkey;
		_Ty* lastval;
		bool first;

	};
}
#endif
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)