You can leverage Search functionality to get the list of all sites the user has access to since search will by default give you security trimmed results.This way you do not need to loop through each site collection,site and check whether user has permission or not.
Below is the code to query all sites which user has access to:
using (SPSite site = new SPSite(SPContext.Current.Site.ID))
KeywordQuery keywordQuery = new KeywordQuery(site);
keywordQuery.QueryText = "contentclass:STS_SITE OR contentclass:STS_Web";//change the query to suit your requirement
keywordQuery.TrimDuplicates = false;
SearchExecutor searchExecutor = new SearchExecutor();
ResultTableCollection resultTableCollection = searchExecutor.ExecuteQuery(keywordQuery);
var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);
int totalRows = resultTables.Count();
var resultTable = resultTables.FirstOrDefault();
dtResults = resultTable.Table;
This approach has a direct dependency on Search crawling, make sure crawling is done in proper intervals, but it provides good performance gain.
See this Link to get the KQL syntax for Lists,Libraries etc and use it in your query.