Attempt to speed up agent idle update by optimizing wearable/visualparam related lookups/iterations a bit more.

Generalized several templates in llstl.h in order to support more containers.
Removed several instances of is_in_map/getWearableCount being followed immediately by another lookup with the same key. find is more efficient, as we get an iterator to use instead of a simple boolean.
This commit is contained in:
Shyotl
2013-04-24 17:52:17 -05:00
parent 6f415118ef
commit ef9fbe2193
14 changed files with 210 additions and 89 deletions

View File

@@ -731,6 +731,7 @@ LLVisualParam* LLWearable::getVisualParam(S32 index) const
void LLWearable::getVisualParams(visual_param_vec_t &list)
{
list.reserve(mVisualParamIndexMap.size());
visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
@@ -783,7 +784,7 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
if (!avatarp) return;
// Pull params
for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
/*for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
{
// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
@@ -794,6 +795,12 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
avatarp->setVisualParamWeight( param_id, weight, FALSE );
}
}*/
for( visual_param_index_map_t::iterator it = mVisualParamIndexMap.begin(); it != mVisualParamIndexMap.end(); ++it )
{
LLVisualParam* param = it->second;
if(!((LLViewerVisualParam*)param)->getCrossWearable())
avatarp->setVisualParamWeight( param->getID(), param->getWeight(), FALSE );
}
}

View File

@@ -31,6 +31,7 @@
#include "llextendedstatus.h"
#include "llpermissions.h"
#include "llsaleinfo.h"
#include "llsortedvector.h"
#include "llwearabletype.h"
#include "lllocaltextureobject.h"
@@ -136,7 +137,7 @@ protected:
typedef std::map<S32, F32> param_map_t;
param_map_t mSavedVisualParamMap; // last saved version of visual params
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
typedef LLSortedVector<S32, LLVisualParam *> visual_param_index_map_t;
visual_param_index_map_t mVisualParamIndexMap;
te_map_t mTEMap; // maps TE to LocalTextureObject

View File

@@ -267,8 +267,7 @@ BOOL LLWearableData::isOnTop(LLWearable* wearable) const
const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const
{
//llassert_always(index == 0);
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
/*wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
return NULL;
@@ -281,49 +280,79 @@ const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type,
else
{
return wearable_vec[index];
}*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && index < wearable_iter->second.size())
{
return wearable_iter->second[index];
}
return NULL;
}
LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
{
U32 count = getWearableCount(type);
/*U32 count = getWearableCount(type);
if ( count == 0)
{
return NULL;
}
return getWearable(type, count-1);
return getWearable(type, count-1);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.back();
}
return NULL;
}
const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
{
U32 count = getWearableCount(type);
/*U32 count = getWearableCount(type);
if ( count == 0)
{
return NULL;
}
return getWearable(type, count-1);
return getWearable(type, count-1);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.back();
}
return NULL;
}
LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
{
if (getWearableCount(type) == 0)
/*if (getWearableCount(type) == 0)
{
return NULL;
}
return getWearable(type, 0);
return getWearable(type, 0);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.front();
}
return NULL;
}
const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
{
if (getWearableCount(type) == 0)
/*if (getWearableCount(type) == 0)
{
return NULL;
}
return getWearable(type, 0);
return getWearable(type, 0);*/
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter != mWearableDatas.end() && !wearable_iter->second.empty())
{
return wearable_iter->second.front();
}
return NULL;
}
U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const

View File

@@ -30,6 +30,7 @@
#include "llavatarappearancedefines.h"
#include "llwearable.h"
#include "llerror.h"
#include "boost/array.hpp"
class LLAvatarAppearance;
@@ -98,8 +99,34 @@ protected:
protected:
LLAvatarAppearance* mAvatarAppearance;
typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
wearableentry_map_t mWearableDatas;
//typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
//Why this weird structure? LLWearableType::WT_COUNT small and known, therefore it's more efficient to make an array of vectors, indexed
//by wearable type. This allows O(1) lookups. This structure simply lets us plug in this optimization without touching any code elsewhere.
typedef boost::array<std::pair<LLWearableType::EType,wearableentry_vec_t>,LLWearableType::WT_COUNT> wearable_array_t;
struct wearableentry_map_t : public wearable_array_t
{
wearableentry_map_t()
{
for(wearable_array_t::size_type i=0;i<size();++i)
at(i).first = (LLWearableType::EType)i;
}
wearable_array_t::iterator find(const LLWearableType::EType& index)
{
if(index < 0 || index >= (S32)size())
return end();
return begin() + index;
}
wearable_array_t::const_iterator find(const LLWearableType::EType& index) const
{
if(index < 0 || index >= (S32)size())
return end();
return begin() + index;
}
wearableentry_vec_t& operator [] (const S32 index) { return at(index).second; }
const wearableentry_vec_t& operator [] (const S32 index) const { return at(index).second; }
};
wearableentry_map_t mWearableDatas; //Array for quicker lookups.
};