Merge lp:~mhr3/unity/faster-models into lp:unity

Proposed by Michal Hruby
Status: Merged
Approved by: Michal Hruby
Approved revision: no longer in the source branch.
Merged at revision: 2688
Proposed branch: lp:~mhr3/unity/faster-models
Merge into: lp:unity
Diff against target: 334 lines (+67/-35)
10 files modified
UnityCore/Model-inl.h (+21/-6)
UnityCore/Model.h (+4/-0)
UnityCore/ModelRowAdaptor.cpp (+12/-5)
UnityCore/ModelRowAdaptor.h (+7/-5)
UnityCore/ResultIterator.cpp (+2/-10)
UnityCore/ResultIterator.h (+1/-2)
dash/LensView.cpp (+12/-3)
dash/LensView.h (+1/-0)
dash/ResultView.cpp (+5/-4)
dash/ResultView.h (+2/-0)
To merge this branch: bzr merge lp:~mhr3/unity/faster-models
Reviewer Review Type Date Requested Status
Gord Allott (community) Approve
Tim Penhey Pending
Review via email: mp+122421@code.launchpad.net

Commit message

Avoid construction of row wrappers

Description of the change

Stop re-constructing row wrapper instances when dee models change. Instead of complete instance creation, only set 3 pointers. This saves a lot of CPU cycles that were wasted by setting getter functions for nux properties, and improves responsiveness when there are lots of results in the dash.

Note that this change limits how we can manipulate the models - for example removing a row from within the row-removed handler could cause invalidation of the result, but since we're not using the models in such recursive way, it's safe.

To post a comment you must log in.
Revision history for this message
Gord Allott (gordallott) wrote :

+1 looks good to me

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

The Jenkins job https://jenkins.qa.ubuntu.com/job/automerge-unity/1282/console reported an error when processing this lp:~mhr3/unity/faster-models branch.
Not merging it.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'UnityCore/Model-inl.h'
--- UnityCore/Model-inl.h 2012-08-17 11:18:38 +0000
+++ UnityCore/Model-inl.h 2012-09-13 09:34:19 +0000
@@ -35,6 +35,9 @@
35template<class RowAdaptor>35template<class RowAdaptor>
36Model<RowAdaptor>::Model()36Model<RowAdaptor>::Model()
37 : model_type_(ModelType::REMOTE)37 : model_type_(ModelType::REMOTE)
38 , cached_adaptor1_(nullptr, nullptr, nullptr)
39 , cached_adaptor2_(nullptr, nullptr, nullptr)
40 , cached_adaptor3_(nullptr, nullptr, nullptr)
38{41{
39 Init();42 Init();
40}43}
@@ -42,6 +45,9 @@
42template<class RowAdaptor>45template<class RowAdaptor>
43Model<RowAdaptor>::Model (ModelType model_type)46Model<RowAdaptor>::Model (ModelType model_type)
44 : model_type_(model_type)47 : model_type_(model_type)
48 , cached_adaptor1_(nullptr, nullptr, nullptr)
49 , cached_adaptor2_(nullptr, nullptr, nullptr)
50 , cached_adaptor3_(nullptr, nullptr, nullptr)
45{51{
46 Init();52 Init();
4753
@@ -118,22 +124,31 @@
118template<class RowAdaptor>124template<class RowAdaptor>
119void Model<RowAdaptor>::OnRowAdded(DeeModel* model, DeeModelIter* iter)125void Model<RowAdaptor>::OnRowAdded(DeeModel* model, DeeModelIter* iter)
120{126{
121 RowAdaptor it(model, iter, renderer_tag_);127 // careful here - adding rows to the model inside the callback
122 row_added.emit(it);128 // will invalidate the cached_adaptor!
129 // This needs to be used as a listener only!
130 cached_adaptor1_.SetTarget(model, iter, renderer_tag_);
131 row_added.emit(cached_adaptor1_);
123}132}
124133
125template<class RowAdaptor>134template<class RowAdaptor>
126void Model<RowAdaptor>::OnRowChanged(DeeModel* model, DeeModelIter* iter)135void Model<RowAdaptor>::OnRowChanged(DeeModel* model, DeeModelIter* iter)
127{136{
128 RowAdaptor it(model, iter, renderer_tag_);137 // careful here - changing rows inside the callback will invalidate
129 row_changed.emit(it);138 // the cached_adaptor!
139 // This needs to be used as a listener only!
140 cached_adaptor2_.SetTarget(model, iter, renderer_tag_);
141 row_changed.emit(cached_adaptor2_);
130}142}
131143
132template<class RowAdaptor>144template<class RowAdaptor>
133void Model<RowAdaptor>::OnRowRemoved(DeeModel* model, DeeModelIter* iter)145void Model<RowAdaptor>::OnRowRemoved(DeeModel* model, DeeModelIter* iter)
134{146{
135 RowAdaptor it(model, iter, renderer_tag_);147 // careful here - removing rows from the model inside the callback
136 row_removed.emit(it);148 // will invalidate the cached_adaptor!
149 // This needs to be used as a listener only!
150 cached_adaptor3_.SetTarget(model, iter, renderer_tag_);
151 row_removed.emit(cached_adaptor3_);
137}152}
138153
139template<class RowAdaptor>154template<class RowAdaptor>
140155
=== modified file 'UnityCore/Model.h'
--- UnityCore/Model.h 2012-04-23 12:29:20 +0000
+++ UnityCore/Model.h 2012-09-13 09:34:19 +0000
@@ -88,6 +88,10 @@
88 glib::SignalManager sig_manager_;88 glib::SignalManager sig_manager_;
89 DeeModelTag* renderer_tag_;89 DeeModelTag* renderer_tag_;
90 ModelType model_type_;90 ModelType model_type_;
91
92 RowAdaptor cached_adaptor1_;
93 RowAdaptor cached_adaptor2_;
94 RowAdaptor cached_adaptor3_;
91};95};
9296
93}97}
9498
=== modified file 'UnityCore/ModelRowAdaptor.cpp'
--- UnityCore/ModelRowAdaptor.cpp 2012-06-19 16:47:56 +0000
+++ UnityCore/ModelRowAdaptor.cpp 2012-09-13 09:34:19 +0000
@@ -45,7 +45,14 @@
45 return *this;45 return *this;
46}46}
4747
48std::string RowAdaptorBase::GetStringAt(int position)48void RowAdaptorBase::SetTarget(DeeModel* model, DeeModelIter* iter, DeeModelTag* tag)
49{
50 model_ = model;
51 iter_ = iter;
52 tag_ = tag;
53}
54
55std::string RowAdaptorBase::GetStringAt(int position) const
49{56{
50 if (!model_ || !iter_)57 if (!model_ || !iter_)
51 return "";58 return "";
@@ -56,28 +63,28 @@
56 return ""; // std::strings don't like null.63 return ""; // std::strings don't like null.
57}64}
5865
59bool RowAdaptorBase::GetBoolAt(int position)66bool RowAdaptorBase::GetBoolAt(int position) const
60{67{
61 if (!model_ || !iter_)68 if (!model_ || !iter_)
62 return 0;69 return 0;
63 return dee_model_get_bool(model_, iter_, position);70 return dee_model_get_bool(model_, iter_, position);
64}71}
6572
66int RowAdaptorBase::GetIntAt(int position)73int RowAdaptorBase::GetIntAt(int position) const
67{74{
68 if (!model_ || !iter_)75 if (!model_ || !iter_)
69 return 0;76 return 0;
70 return dee_model_get_int32(model_, iter_, position);77 return dee_model_get_int32(model_, iter_, position);
71}78}
7279
73unsigned int RowAdaptorBase::GetUIntAt(int position)80unsigned int RowAdaptorBase::GetUIntAt(int position) const
74{81{
75 if (!model_ || !iter_)82 if (!model_ || !iter_)
76 return 0;83 return 0;
77 return dee_model_get_uint32(model_, iter_, position);84 return dee_model_get_uint32(model_, iter_, position);
78}85}
7986
80float RowAdaptorBase::GetFloatAt(int position)87float RowAdaptorBase::GetFloatAt(int position) const
81{88{
82 if (!model_ || !iter_)89 if (!model_ || !iter_)
83 return 0.0;90 return 0.0;
8491
=== modified file 'UnityCore/ModelRowAdaptor.h'
--- UnityCore/ModelRowAdaptor.h 2012-06-19 16:47:56 +0000
+++ UnityCore/ModelRowAdaptor.h 2012-09-13 09:34:19 +0000
@@ -52,11 +52,13 @@
52 RowAdaptorBase(RowAdaptorBase const& other);52 RowAdaptorBase(RowAdaptorBase const& other);
53 RowAdaptorBase& operator=(RowAdaptorBase const& other);53 RowAdaptorBase& operator=(RowAdaptorBase const& other);
5454
55 std::string GetStringAt(int position);55 std::string GetStringAt(int position) const;
56 bool GetBoolAt(int position);56 bool GetBoolAt(int position) const;
57 int GetIntAt(int position);57 int GetIntAt(int position) const;
58 unsigned int GetUIntAt(int position);58 unsigned int GetUIntAt(int position) const;
59 float GetFloatAt(int position);59 float GetFloatAt(int position) const;
60
61 void SetTarget(DeeModel* model, DeeModelIter* iter, DeeModelTag* tag);
6062
61 template<typename T>63 template<typename T>
62 void set_renderer(T renderer);64 void set_renderer(T renderer);
6365
=== modified file 'UnityCore/ResultIterator.cpp'
--- UnityCore/ResultIterator.cpp 2012-08-13 08:18:25 +0000
+++ UnityCore/ResultIterator.cpp 2012-09-13 09:34:19 +0000
@@ -34,7 +34,6 @@
34 , iter_(model ? dee_model_get_first_iter(model) : NULL)34 , iter_(model ? dee_model_get_first_iter(model) : NULL)
35 , tag_(NULL)35 , tag_(NULL)
36 , iter_result_(model_, iter_, tag_)36 , iter_result_(model_, iter_, tag_)
37 , cache_invalidated_(false)
38{37{
39}38}
4039
@@ -43,7 +42,6 @@
43 , iter_(iter)42 , iter_(iter)
44 , tag_(tag)43 , tag_(tag)
45 , iter_result_(model_, iter_, tag_)44 , iter_result_(model_, iter_, tag_)
46 , cache_invalidated_(false)
47{45{
48}46}
4947
@@ -57,8 +55,7 @@
57 model_ = rhs.model_;55 model_ = rhs.model_;
58 iter_ = rhs.iter_;56 iter_ = rhs.iter_;
59 tag_ = rhs.tag_;57 tag_ = rhs.tag_;
60 iter_result_ = Result(model_, iter_, tag_);58 iter_result_.SetTarget(model_, iter_, tag_);
61 cache_invalidated_ = false;
6259
63 return *this;60 return *this;
64}61}
@@ -66,7 +63,6 @@
66ResultIterator& ResultIterator::operator++()63ResultIterator& ResultIterator::operator++()
67{64{
68 iter_ = dee_model_next(model_, iter_);65 iter_ = dee_model_next(model_, iter_);
69 cache_invalidated_ = true;
70 return *this;66 return *this;
71}67}
7268
@@ -78,7 +74,6 @@
78 for (int index = 0; index < count; index++)74 for (int index = 0; index < count; index++)
79 iter_ = dee_model_next(model_, iter_);75 iter_ = dee_model_next(model_, iter_);
80 76
81 cache_invalidated_ = true;
82 return *this;77 return *this;
83}78}
8479
@@ -99,7 +94,6 @@
99ResultIterator& ResultIterator::operator--()94ResultIterator& ResultIterator::operator--()
100{95{
101 iter_ = dee_model_prev(model_, iter_);96 iter_ = dee_model_prev(model_, iter_);
102 cache_invalidated_ = true;
103 return *this;97 return *this;
104}98}
10599
@@ -111,7 +105,6 @@
111 for (int index = 0; index < count; index++)105 for (int index = 0; index < count; index++)
112 iter_ = dee_model_prev(model_, iter_);106 iter_ = dee_model_prev(model_, iter_);
113107
114 cache_invalidated_ = true;
115 return *this;108 return *this;
116}109}
117110
@@ -131,8 +124,7 @@
131124
132Result& ResultIterator::operator*()125Result& ResultIterator::operator*()
133{126{
134 if (cache_invalidated_)127 iter_result_.SetTarget(model_, iter_, tag_);
135 iter_result_ = Result(model_, iter_, tag_);
136 return iter_result_;128 return iter_result_;
137}129}
138130
139131
=== modified file 'UnityCore/ResultIterator.h'
--- UnityCore/ResultIterator.h 2012-08-13 08:18:25 +0000
+++ UnityCore/ResultIterator.h 2012-09-13 09:34:19 +0000
@@ -37,7 +37,7 @@
37public:37public:
38 ResultIterator(glib::Object<DeeModel> model);38 ResultIterator(glib::Object<DeeModel> model);
39 ResultIterator(glib::Object<DeeModel> model, DeeModelIter* iter_, DeeModelTag* tag);39 ResultIterator(glib::Object<DeeModel> model, DeeModelIter* iter_, DeeModelTag* tag);
40 ResultIterator(ResultIterator const& copy) : model_(copy.model_), iter_(copy.iter_), tag_(copy.tag_), iter_result_(copy.iter_result_), cache_invalidated_(false){};40 ResultIterator(ResultIterator const& copy) : model_(copy.model_), iter_(copy.iter_), tag_(copy.tag_), iter_result_(copy.iter_result_){};
4141
42 ResultIterator& operator=(ResultIterator const& rhs);42 ResultIterator& operator=(ResultIterator const& rhs);
4343
@@ -93,7 +93,6 @@
93 DeeModelIter* iter_;93 DeeModelIter* iter_;
94 DeeModelTag* tag_;94 DeeModelTag* tag_;
95 Result iter_result_; 95 Result iter_result_;
96 bool cache_invalidated_;
97};96};
9897
99}98}
10099
=== modified file 'dash/LensView.cpp'
--- dash/LensView.cpp 2012-08-31 15:46:18 +0000
+++ dash/LensView.cpp 2012-09-13 09:34:19 +0000
@@ -440,6 +440,8 @@
440void LensView::OnResultAdded(Result const& result)440void LensView::OnResultAdded(Result const& result)
441{441{
442 try {442 try {
443 // Anything done in this method needs to be super fast, if in doubt, add
444 // it to the model_updated_timeout_ callback!
443 PlacesGroup* group = categories_.at(result.category_index);445 PlacesGroup* group = categories_.at(result.category_index);
444446
445 std::string uri = result.uri;447 std::string uri = result.uri;
@@ -453,9 +455,16 @@
453 CheckNoResults(Lens::Hints());455 CheckNoResults(Lens::Hints());
454 }456 }
455457
456 // Check if all results so far are from one category458 if (!model_updated_timeout_)
457 // If so, then expand that category.459 {
458 CheckCategoryExpansion();460 model_updated_timeout_.reset(new glib::Idle([&] () {
461 // Check if all results so far are from one category
462 // If so, then expand that category.
463 CheckCategoryExpansion();
464 model_updated_timeout_.reset();
465 return false;
466 }, glib::Source::Priority::HIGH));
467 }
459 } catch (std::out_of_range& oor) {468 } catch (std::out_of_range& oor) {
460 LOG_WARN(logger) << "Result does not have a valid category index: "469 LOG_WARN(logger) << "Result does not have a valid category index: "
461 << boost::lexical_cast<unsigned int>(result.category_index)470 << boost::lexical_cast<unsigned int>(result.category_index)
462471
=== modified file 'dash/LensView.h'
--- dash/LensView.h 2012-08-29 14:50:19 +0000
+++ dash/LensView.h 2012-09-13 09:34:19 +0000
@@ -126,6 +126,7 @@
126126
127 UBusManager ubus_manager_;127 UBusManager ubus_manager_;
128 glib::Source::UniquePtr fix_rendering_idle_;128 glib::Source::UniquePtr fix_rendering_idle_;
129 glib::Source::UniquePtr model_updated_timeout_;
129 int last_good_filter_model_;130 int last_good_filter_model_;
130 glib::Source::UniquePtr fix_filter_models_idle_;131 glib::Source::UniquePtr fix_filter_models_idle_;
131};132};
132133
=== modified file 'dash/ResultView.cpp'
--- dash/ResultView.cpp 2012-08-24 08:43:50 +0000
+++ dash/ResultView.cpp 2012-09-13 09:34:19 +0000
@@ -44,6 +44,7 @@
44 : View(NUX_FILE_LINE_PARAM)44 : View(NUX_FILE_LINE_PARAM)
45 , expanded(true)45 , expanded(true)
46 , renderer_(NULL)46 , renderer_(NULL)
47 , cached_result_(nullptr, nullptr, nullptr)
47{48{
48 expanded.changed.connect([&](bool value)49 expanded.changed.connect([&](bool value)
49 {50 {
@@ -99,14 +100,14 @@
99100
100void ResultView::OnRowAdded(DeeModel* model, DeeModelIter* iter)101void ResultView::OnRowAdded(DeeModel* model, DeeModelIter* iter)
101{102{
102 Result result(model, iter, renderer_tag_);103 cached_result_.SetTarget(model, iter, renderer_tag_);
103 AddResult(result);104 AddResult(cached_result_);
104}105}
105106
106void ResultView::OnRowRemoved(DeeModel* model, DeeModelIter* iter)107void ResultView::OnRowRemoved(DeeModel* model, DeeModelIter* iter)
107{108{
108 Result result(model, iter, renderer_tag_);109 cached_result_.SetTarget(model, iter, renderer_tag_);
109 RemoveResult(result);110 RemoveResult(cached_result_);
110}111}
111112
112void ResultView::SetModel(glib::Object<DeeModel> const& model, DeeModelTag* tag)113void ResultView::SetModel(glib::Object<DeeModel> const& model, DeeModelTag* tag)
113114
=== modified file 'dash/ResultView.h'
--- dash/ResultView.h 2012-08-22 08:16:02 +0000
+++ dash/ResultView.h 2012-09-13 09:34:19 +0000
@@ -91,6 +91,8 @@
91private:91private:
92 void OnRowAdded(DeeModel* model, DeeModelIter* iter);92 void OnRowAdded(DeeModel* model, DeeModelIter* iter);
93 void OnRowRemoved(DeeModel* model, DeeModelIter* iter);93 void OnRowRemoved(DeeModel* model, DeeModelIter* iter);
94
95 Result cached_result_;
94};96};
9597
96}98}