(view as text)
diff --git a/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.h b/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.h
index a7b21a9..7466f74 100644
--- a/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.h
+++ b/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.h
@@ -38,6 +38,11 @@ public:
 	{
 		return puid == r.puid && vuid == r.vuid;
 	}
+
+	size_t hash () const
+	{
+		return vuid.hash() ^ puid.hash();
+	}
 };
 
 
@@ -78,7 +83,14 @@ public:
 		}
 	};
 
-	typedef std::map<SHADERUID, PCacheEntry> PCache;
+	template<typename UID> struct ShaderUidHash
+	{
+		size_t operator()(UID const& uid) const
+		{
+			return uid.hash();
+		}
+	};
+	typedef std::unordered_map<SHADERUID, PCacheEntry, ShaderUidHash<SHADERUID>> PCache;
 
 	static PCacheEntry GetShaderProgram(void);
 	static GLuint GetCurrentProgram(void);
diff --git a/Source/Core/VideoCommon/Src/ShaderGenCommon.h b/Source/Core/VideoCommon/Src/ShaderGenCommon.h
index b56e9f2..088f1be 100644
--- a/Source/Core/VideoCommon/Src/ShaderGenCommon.h
+++ b/Source/Core/VideoCommon/Src/ShaderGenCommon.h
@@ -102,6 +102,21 @@ public:
 		return memcmp(this->values, obj.values, data.NumValues() * sizeof(*values)) < 0;
 	}
 
+	size_t hash () const
+	{
+		size_t r = 0;
+		u32 i=0;
+		for(; i<data.NumValues()+1-sizeof(size_t); i+=sizeof(size_t))
+		{
+			r ^= *(size_t*)(values+i);
+		}
+		for(; i<data.NumValues(); i++)
+		{
+			r ^= values[i];
+		}
+		return r;
+	}
+
 	template<class T>
 	inline T& GetUidData() { return data; }