diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index b291c97344936bba7adefe7abd001fa98c82097e..4f9cd254ec8558ed9d79483dcc0e720a9979193b 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -116,6 +116,7 @@ void LLViewerTextureList::doPreloadImages()
 	llassert_always(mInitialized) ;
 	llassert_always(mImageList.empty()) ;
 	llassert_always(mUUIDMap.empty()) ;
+	llassert_always(mUUIDHashMap.empty());
 
 	// Set the "missing asset" image
 	LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
@@ -229,8 +230,8 @@ void LLViewerTextureList::doPrefetchImages()
         file.close();
 	}
     S32 texture_count = 0;
-	for (LLSD::array_iterator iter = imagelist.beginArray();
-		 iter != imagelist.endArray(); ++iter)
+	for (LLSD::array_const_iterator iter = imagelist.beginArray(), end = imagelist.endArray();
+		 iter != end; ++iter)
 	{
 		LLSD imagesd = *iter;
 		LLUUID uuid = imagesd["uuid"];
@@ -266,10 +267,8 @@ void LLViewerTextureList::shutdown()
 	// Write out list of currently loaded textures for precaching on startup
 	typedef std::set<std::pair<S32,LLViewerFetchedTexture*> > image_area_list_t;
 	image_area_list_t image_area_list;
-	for (image_priority_list_t::iterator iter = mImageList.begin();
-		 iter != mImageList.end(); ++iter)
+	for (LLViewerFetchedTexture* image : mImageList)
 	{
-		LLViewerFetchedTexture* image = *iter;
 		if (!image->hasGLTexture() ||
 			!image->getUseDiscard() ||
 			image->needsAux() ||
@@ -287,7 +286,7 @@ void LLViewerTextureList::shutdown()
 		if (desired >= 0 && desired < MAX_DISCARD_LEVEL)
 		{
 			S32 pixel_area = image->getWidth(desired) * image->getHeight(desired);
-			image_area_list.insert(std::make_pair(pixel_area, image));
+			image_area_list.emplace(pixel_area, image);
 		}
 	}
 	
@@ -327,7 +326,8 @@ void LLViewerTextureList::shutdown()
 	mLoadingStreamList.clear();
 	mCreateTextureList.clear();
 	mFastCacheList.clear();
-	
+
+	mUUIDHashMap.clear();	
 	mUUIDMap.clear();
 	
 	mImageList.clear();
@@ -338,15 +338,14 @@ void LLViewerTextureList::shutdown()
 void LLViewerTextureList::dump()
 {
 	LL_INFOS() << "LLViewerTextureList::dump()" << LL_ENDL;
-	for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it)
-	{
-		LLViewerFetchedTexture* image = *it;
-
+	for (LLViewerFetchedTexture* image : mImageList)
+    {
 		LL_INFOS() << "priority " << image->getDecodePriority()
 		<< " boost " << image->getBoostLevel()
 		<< " size " << image->getWidth() << "x" << image->getHeight()
 		<< " discard " << image->getDiscardLevel()
 		<< " desired " << image->getDesiredDiscardLevel()
+		<< " references " << image->getNumRefs()
 		<< " http://asset.siva.lindenlab.com/" << image->getID() << ".texture"
 		<< LL_ENDL;
 	}
@@ -625,8 +624,8 @@ void LLViewerTextureList::findTexturesByID(const LLUUID &image_id, std::vector<L
 
 LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLTextureKey &search_key)
 {
-    uuid_map_t::iterator iter = mUUIDMap.find(search_key);
-    if (iter == mUUIDMap.end())
+    auto iter = mUUIDHashMap.find(search_key);
+    if (iter == mUUIDHashMap.cend())
         return NULL;
     return iter->second;
 }
@@ -678,8 +677,8 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
 			<< " but doesn't have mInImageList set"
 			<< " ref count is " << image->getNumRefs()
 			<< LL_ENDL;
-		uuid_map_t::iterator iter = mUUIDMap.find(LLTextureKey(image->getID(), (ETexListType)image->getTextureListType()));
-		if(iter == mUUIDMap.end())
+		auto iter = mUUIDHashMap.find(LLTextureKey(image->getID(), (ETexListType)image->getTextureListType()));
+		if(iter == mUUIDHashMap.cend())
 		{
 			LL_INFOS() << "Image  " << image->getID() << " is also not in mUUIDMap!" << LL_ENDL ;
 		}
@@ -721,7 +720,8 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy
 	sNumImages++;
 
 	addImageToList(new_image);
-	mUUIDMap[key] = new_image;
+	mUUIDMap.insert_or_assign(key, new_image);
+	mUUIDHashMap.insert_or_assign(key, new_image);
 	new_image->setTextureListType(tex_type);
 }
 
@@ -736,6 +736,7 @@ void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)
 		}
 		LLTextureKey key(image->getID(), (ETexListType)image->getTextureListType());
 		llverify(mUUIDMap.erase(key) == 1);
+		llverify(mUUIDHashMap.erase(key) == 1);
 		sNumImages--;
 		removeImageFromList(image);
 	}
@@ -856,10 +857,8 @@ void LLViewerTextureList::clearFetchingRequests()
 
 	LLAppViewer::getTextureFetch()->deleteAllRequests();
 
-	for (image_priority_list_t::iterator iter = mImageList.begin();
-		 iter != mImageList.end(); ++iter)
-	{
-		LLViewerFetchedTexture* imagep = *iter;
+	for (LLViewerFetchedTexture* imagep : mImageList)
+    {
 		imagep->forceToDeleteRequest() ;
 	}
 }
@@ -1205,16 +1204,14 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
 		 iter != mImageList.end(); )
 	{
 		LLViewerFetchedTexture* imagep = *iter++;
-		image_list.push_back(imagep);
+		image_list.emplace_back(imagep);
 		imagep->setInImageList(FALSE) ;
 	}
 
 	llassert_always(image_list.size() == mImageList.size()) ;
 	mImageList.clear();
-	for (std::vector<LLPointer<LLViewerFetchedTexture> >::iterator iter = image_list.begin();
-		 iter != image_list.end(); ++iter)
+	for (LLViewerFetchedTexture* imagep : image_list)
 	{
-		LLViewerFetchedTexture* imagep = *iter;
 		imagep->processTextureStats();
 		F32 decode_priority = imagep->calcDecodePriority();
 		imagep->setDecodePriority(decode_priority);
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index de66921b785dd83fc786c1ecc9facc7868fed3d1..148058b17e6a24e6696efe1d2a88bab8189e6bc5 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -36,6 +36,8 @@
 #include <set>
 #include "lluiimage.h"
 
+#include "absl/container/flat_hash_map.h"
+
 const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128;
 
 const BOOL MIPMAP_YES = TRUE;
@@ -83,6 +85,17 @@ struct LLTextureKey
             return key1.textureType < key2.textureType;
         }
     }
+
+	friend bool operator==(const LLTextureKey& lhs, const LLTextureKey& rhs)
+	{
+		return lhs.textureId == rhs.textureId && lhs.textureType == rhs.textureType;
+	}
+
+	template <typename H>
+	friend H AbslHashValue(H h, const LLTextureKey& id) 
+	{
+		return H::combine(std::move(h), id.textureId, id.textureType);
+	}
 };
 
 class LLViewerTextureList
@@ -194,7 +207,7 @@ class LLViewerTextureList
 	
 	// Request image from a specific host, used for baked avatar textures.
 	// Implemented in header in case someone changes default params above. JC
-	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, FTType f_type, LLHost host)
+	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, FTType f_type, const LLHost& host)
 	{ return getImage(image_id, f_type, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	
 
 public:
@@ -210,8 +223,10 @@ class LLViewerTextureList
 	BOOL mForceResetTextureStats;
     
 private:
-    typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t;
+    using uuid_map_t = std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> >;
+    using uuid_hash_map_t = absl::flat_hash_map< LLTextureKey, LLViewerFetchedTexture* >;
     uuid_map_t mUUIDMap;
+    uuid_hash_map_t mUUIDHashMap;
     LLTextureKey mLastUpdateKey;
     LLTextureKey mLastFetchKey;
 	
@@ -268,7 +283,7 @@ class LLUIImageList final : public LLImageProviderInterface, public LLSingleton<
 		LLRect mImageClipRegion;
 	};
 
-	typedef std::map< std::string, LLPointer<LLUIImage> > uuid_ui_image_map_t;
+	typedef absl::flat_hash_map< std::string, LLPointer<LLUIImage> > uuid_ui_image_map_t;
 	uuid_ui_image_map_t mUIImages;
 
 	//