Merge pull request #2018 from G10h4ck/memory_optimization

Reduce memory usage due to copying in RsQThreadUtils::postToObject
This commit is contained in:
G10h4ck 2020-06-25 11:30:06 +02:00 committed by GitHub
commit 638ef80788
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 57 deletions

View File

@ -24,6 +24,7 @@
#include <QMenu> #include <QMenu>
#include <algorithm> #include <algorithm>
#include <memory>
#include <retroshare/rspeers.h> #include <retroshare/rspeers.h>
#include <retroshare/rsidentity.h> #include <retroshare/rsidentity.h>
@ -696,34 +697,32 @@ void CreateCircleDialog::loadIdentities()
{ {
RsThread::async([this]() RsThread::async([this]()
{ {
std::list<RsGroupMetaData> ids_meta; std::list<RsGroupMetaData> ids_meta;
if(!rsIdentity->getIdentitiesSummaries(ids_meta)) if(!rsIdentity->getIdentitiesSummaries(ids_meta))
{ {
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve identities ids for all identities" << std::endl; RS_ERR("failed to retrieve identities ids for all identities");
return; return;
} }
std::set<RsGxsId> ids;
for(auto& meta:ids_meta) std::set<RsGxsId> ids;
ids.insert(RsGxsId(meta.mGroupId)) ; for(auto& meta:ids_meta) ids.insert(RsGxsId(meta.mGroupId));
std::vector<RsGxsIdGroup> id_groups; auto id_groups = std::make_unique<std::vector<RsGxsIdGroup>>();
if(!rsIdentity->getIdentitiesInfo(ids, *id_groups))
if(!rsIdentity->getIdentitiesInfo(ids,id_groups))
{ {
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve identities group info for all identities" << std::endl; RS_ERR("failed to retrieve identities group info for all identities");
return; return;
} }
RsQThreadUtils::postToObject( [id_groups,this]() RsQThreadUtils::postToObject(
[id_groups = std::move(id_groups), this]()
{ {
/* Here it goes any code you want to be executed on the Qt Gui /* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information * thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */ * after a blocking call to RetroShare API complete */
fillIdentitiesList(id_groups) ; fillIdentitiesList(*id_groups);
}, this ); }, this );
}); });

View File

@ -47,6 +47,7 @@
#include "util/misc.h" #include "util/misc.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
#include "util/rstime.h" #include "util/rstime.h"
#include "util/rsdebug.h"
#include "retroshare/rsgxsflags.h" #include "retroshare/rsgxsflags.h"
#include "retroshare/rsmsgs.h" #include "retroshare/rsmsgs.h"
@ -55,6 +56,7 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
#include <memory>
/****** /******
* #define ID_DEBUG 1 * #define ID_DEBUG 1
@ -506,21 +508,24 @@ void IdDialog::updateCircles()
std::cerr << "Retrieving post data for post " << mThreadId << std::endl; std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif #endif
std::list<RsGroupMetaData> circle_metas ; /* This can be big so use a smart pointer to just copy the pointer
* instead of copying the whole list accross the lambdas */
auto circle_metas = std::make_unique<std::list<RsGroupMetaData>>();
if(!rsGxsCircles->getCirclesSummaries(circle_metas)) if(!rsGxsCircles->getCirclesSummaries(*circle_metas))
{ {
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve circles group info list" << std::endl; RS_ERR("failed to retrieve circles group info list");
return; return;
} }
RsQThreadUtils::postToObject( [circle_metas,this]() RsQThreadUtils::postToObject(
[circle_metas = std::move(circle_metas), this]()
{ {
/* Here it goes any code you want to be executed on the Qt Gui /* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information * thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */ * after a blocking call to RetroShare API complete */
loadCircles(circle_metas); loadCircles(*circle_metas);
}, this ); }, this );
@ -1305,19 +1310,17 @@ void IdDialog::updateIdList()
return; return;
} }
std::map<RsGxsGroupId,RsGxsIdGroup> ids_set; auto ids_set = std::make_unique<std::map<RsGxsGroupId,RsGxsIdGroup>>();
for(auto it(groups.begin()); it!=groups.end(); ++it)
(*ids_set)[(*it).mMeta.mGroupId] = *it;
for(auto it(groups.begin());it!=groups.end();++it) RsQThreadUtils::postToObject(
ids_set[(*it).mMeta.mGroupId] = *it; [ids_set = std::move(ids_set), this] ()
RsQThreadUtils::postToObject( [ids_set,this]()
{ {
/* Here it goes any code you want to be executed on the Qt Gui /* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information * thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */ * after a blocking call to RetroShare API complete */
loadIdentities(*ids_set);
loadIdentities(ids_set);
}, this ); }, this );
}); });

View File

@ -210,8 +210,8 @@ void IdEditDialog::setupExistingId(const RsGxsGroupId& keyId)
RsThread::async([this,keyId]() RsThread::async([this,keyId]()
{ {
std::vector<RsGxsIdGroup> datavector; std::vector<RsGxsIdGroup> datavector;
bool res = rsIdentity->getIdentitiesInfo(
bool res = rsIdentity->getIdentitiesInfo(std::set<RsGxsId>({(RsGxsId)keyId}),datavector); std::set<RsGxsId>({(RsGxsId)keyId}), datavector );
RsQThreadUtils::postToObject( [this,keyId,res,datavector]() RsQThreadUtils::postToObject( [this,keyId,res,datavector]()
{ {

View File

@ -36,6 +36,7 @@
#include <retroshare/rsstatus.h> #include <retroshare/rsstatus.h>
#include <algorithm> #include <algorithm>
#include <memory>
#define COLUMN_NAME 0 #define COLUMN_NAME 0
#define COLUMN_CHECK 0 #define COLUMN_CHECK 0
@ -250,24 +251,21 @@ void FriendSelectionWidget::loadIdentities()
if(!rsIdentity->getIdentitiesSummaries(ids_meta)) if(!rsIdentity->getIdentitiesSummaries(ids_meta))
{ {
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve identities group info for all identities" << std::endl; RS_ERR("failed to retrieve identities group info for all identities");
return; return;
} }
std::vector<RsGxsGroupId> ids;
for(auto& meta:ids_meta) auto ids = std::make_unique<std::vector<RsGxsGroupId>>();
ids.push_back(meta.mGroupId) ; for(auto& meta: ids_meta) ids->push_back(meta.mGroupId);
RsQThreadUtils::postToObject( [ids,this]() RsQThreadUtils::postToObject(
[ids = std::move(ids), this]()
{ {
/* Here it goes any code you want to be executed on the Qt Gui // We do that is the GUI thread. Dont try it on another thread!
* thread, for example to update the data model with new information gxsIds = *ids;
* after a blocking call to RetroShare API complete */ /* TODO: To furter optimize away a copy gxsIds could be a unique_ptr
* too */
gxsIds = ids; // we do that is the GUI thread. Dont try it on another thread! fillList();
fillList() ;
}, this ); }, this );
}); });
} }

View File

@ -20,6 +20,7 @@
#include <iostream> #include <iostream>
#include <time.h> #include <time.h>
#include <memory>
#include <QDateTime> #include <QDateTime>
#include <QFontMetrics> #include <QFontMetrics>
@ -463,24 +464,25 @@ void GxsTransportStatistics::loadGroups()
#ifdef DEBUG_FORUMS #ifdef DEBUG_FORUMS
std::cerr << "Retrieving post data for post " << mThreadId << std::endl; std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif #endif
std::map<RsGxsGroupId,RsGxsTransGroupStatistics> stats; auto stats = std::make_unique<
std::map<RsGxsGroupId,RsGxsTransGroupStatistics> >();
if(!rsGxsTrans->getGroupStatistics(stats)) if(!rsGxsTrans->getGroupStatistics(*stats))
{ {
RsErr() << "Cannot retrieve group statistics in GxsTransportStatistics" << std::endl; RS_ERR("Cannot retrieve group statistics in GxsTransportStatistics");
return; return;
} }
RsQThreadUtils::postToObject( [stats,this]() RsQThreadUtils::postToObject(
[stats = std::move(stats), this]()
{ {
/* Here it goes any code you want to be executed on the Qt Gui /* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information * thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */ * after a blocking call to RetroShare API complete */
mGroupStats = stats; // TODO: consider making mGroupStats an unique_ptr to avoid copying
mGroupStats = *stats;
updateContent(); updateContent();
mStateHelper->setLoading(GXSTRANS_GROUP_META, false); mStateHelper->setLoading(GXSTRANS_GROUP_META, false);
}, this ); }, this );

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
* util/qthreadutils.h * * util/qthreadutils.h *
* * * *
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> * * Copyright (C) 2018-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as * * it under the terms of the GNU Affero General Public License as *
@ -27,7 +27,9 @@
#include <QtGlobal> #include <QtGlobal>
#include <QtCore> #include <QtCore>
#include <type_traits> #include <type_traits>
#include <utility>
namespace RsQThreadUtils { namespace RsQThreadUtils {
@ -44,7 +46,7 @@ void postToObject(F &&fun, QObject *obj = qApp)
QObject src; QObject src;
auto type = obj->metaObject(); auto type = obj->metaObject();
QObject::connect( &src, &QObject::destroyed, obj, QObject::connect( &src, &QObject::destroyed, obj,
[fun, type, obj] [fun = std::move(fun), type, obj]
{ {
// ensure that the object is not being destructed // ensure that the object is not being destructed
if (obj->metaObject()->inherits(type)) fun(); if (obj->metaObject()->inherits(type)) fun();