From 12ebcc322b85fbd05254a19b0cec6f4d568ee7eb Mon Sep 17 00:00:00 2001 From: mattak Date: Tue, 5 Sep 2017 01:21:25 +0900 Subject: [PATCH 1/3] issues/97 refactor(IStateClone): replaced by ICloneable --- Assets/Plugins/Unidux/Scripts/IStateClone.cs | 7 ------- Assets/Plugins/Unidux/Scripts/IStateClone.cs.meta | 12 ------------ Assets/Plugins/Unidux/Scripts/StateBase.cs | 7 ++++--- Assets/Plugins/Unidux/Scripts/Store.cs | 2 +- .../Test/Editor/Performance/ClonePerformanceTest.cs | 2 +- Assets/Plugins/Unidux/Test/Editor/StateBaseTest.cs | 2 +- Assets/Plugins/Unidux/Test/Editor/StateCloneTest.cs | 11 ++++++----- 7 files changed, 13 insertions(+), 30 deletions(-) delete mode 100644 Assets/Plugins/Unidux/Scripts/IStateClone.cs delete mode 100644 Assets/Plugins/Unidux/Scripts/IStateClone.cs.meta diff --git a/Assets/Plugins/Unidux/Scripts/IStateClone.cs b/Assets/Plugins/Unidux/Scripts/IStateClone.cs deleted file mode 100644 index d6c078a..0000000 --- a/Assets/Plugins/Unidux/Scripts/IStateClone.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Unidux -{ - public interface IStateClone - { - TValue Clone() where TValue : IStateClone; - } -} \ No newline at end of file diff --git a/Assets/Plugins/Unidux/Scripts/IStateClone.cs.meta b/Assets/Plugins/Unidux/Scripts/IStateClone.cs.meta deleted file mode 100644 index ebda2b1..0000000 --- a/Assets/Plugins/Unidux/Scripts/IStateClone.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5c2d230e5dd65459fae5e075afcff2d7 -timeCreated: 1467555921 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/Unidux/Scripts/StateBase.cs b/Assets/Plugins/Unidux/Scripts/StateBase.cs index 2a3b26e..116389f 100644 --- a/Assets/Plugins/Unidux/Scripts/StateBase.cs +++ b/Assets/Plugins/Unidux/Scripts/StateBase.cs @@ -4,11 +4,12 @@ namespace Unidux { [Serializable] - public class StateBase : IState, IStateClone, IStateChanged + public class StateBase : IState, IStateChanged, ICloneable { - public virtual TValue Clone() where TValue : IStateClone + public virtual object Clone() { - return (TValue) StateUtil.MemoryClone(this); + // It's slow. in case of requiring performance override this deep clone method by your code. + return StateUtil.MemoryClone(this); } public bool IsStateChanged { get; private set; } diff --git a/Assets/Plugins/Unidux/Scripts/Store.cs b/Assets/Plugins/Unidux/Scripts/Store.cs index 39cc62b..8fb4c2d 100644 --- a/Assets/Plugins/Unidux/Scripts/Store.cs +++ b/Assets/Plugins/Unidux/Scripts/Store.cs @@ -101,7 +101,7 @@ public void ForceUpdate() lock (this._state) { // Prevent writing state object - fixedState = this._state.Clone(); + fixedState = (TState) this._state.Clone(); // The function may slow StateUtil.ResetStateChanged(this._state); diff --git a/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs b/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs index 5cb6005..247c7e3 100644 --- a/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs +++ b/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs @@ -23,7 +23,7 @@ public void CloneTest() { watch.Reset(); watch.Start(); - var clone1 = state.Clone(); + var clone1 = (SampleState)state.Clone(); watch.Stop(); UnityEngine.Debug.Log("Clone1: " + watch.Elapsed.Milliseconds + "[ms]"); } diff --git a/Assets/Plugins/Unidux/Test/Editor/StateBaseTest.cs b/Assets/Plugins/Unidux/Test/Editor/StateBaseTest.cs index 1535e67..3c4c021 100644 --- a/Assets/Plugins/Unidux/Test/Editor/StateBaseTest.cs +++ b/Assets/Plugins/Unidux/Test/Editor/StateBaseTest.cs @@ -12,7 +12,7 @@ public void CloneTest() var sample1 = new SampleState(); sample1.List = new List() {"a", "b", "c"}; - var sample2 = sample1.Clone(); + var sample2 = (SampleState)sample1.Clone(); sample2.List[1] = "bb"; Assert.AreEqual(new List() {"a", "b", "c"}, sample1.List); Assert.AreEqual(new List() {"a", "bb", "c"}, sample2.List); diff --git a/Assets/Plugins/Unidux/Test/Editor/StateCloneTest.cs b/Assets/Plugins/Unidux/Test/Editor/StateCloneTest.cs index 3a785b0..e043d1c 100644 --- a/Assets/Plugins/Unidux/Test/Editor/StateCloneTest.cs +++ b/Assets/Plugins/Unidux/Test/Editor/StateCloneTest.cs @@ -1,9 +1,10 @@ -using NUnit.Framework; +using System; +using NUnit.Framework; namespace Unidux { public class StateCloneTest { - class Hoge : IStateClone + class Hoge : ICloneable { private bool Flag = false; @@ -17,9 +18,9 @@ public bool GetFlag() return this.Flag; } - public T Clone() where T : IStateClone + public object Clone() { - return (T) MemberwiseClone(); + return MemberwiseClone(); } } @@ -47,7 +48,7 @@ public void CloneTest() Assert.AreEqual(true, hoge1.GetFlag()); Assert.AreEqual(100, hoge1.GetCount()); - var hoge2 = hoge1.Clone(); + var hoge2 = (HogeHoge)hoge1.Clone(); Assert.AreEqual(true, hoge2.GetFlag()); Assert.AreEqual(100, hoge2.GetCount()); } From d0492e10b6aa9625a725671d51ee181fa0399cc3 Mon Sep 17 00:00:00 2001 From: mattak Date: Tue, 5 Sep 2017 01:22:11 +0900 Subject: [PATCH 2/3] issues/97 doc(README): performance tips for State Clone --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 9ea1134..1e0e51f 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,27 @@ Foo.Instance The instance of the base class. +# TIPS + +## Performance of object cloning + +Default implemention of `StateBase.Clone()` is not fast, because it uses `BinaryFormatter` & `MemoryStream`. +And Unidux creates new State on every State chaning (it affects a few milliseconds). +So in case of requiring performance, override clone method with your own logic. + +e.g. + +``` +[Serializable] +class State : StateBase +{ + public override object Clone() + { + // implement your custom deep clone code + } +} +``` + # Thanks - [@austinmao](https://github.com/austinmao) for suggestion of Ducks and UniRx. From 7908f013b518a94b20539a5340336f0a83bcc089 Mon Sep 17 00:00:00 2001 From: mattak Date: Tue, 5 Sep 2017 01:27:27 +0900 Subject: [PATCH 3/3] issues/97 test(ClonePerformanceTest): change implementation of Clone function --- .../Test/Editor/Performance/ClonePerformanceTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs b/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs index 247c7e3..f2326c7 100644 --- a/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs +++ b/Assets/Plugins/Unidux/Test/Editor/Performance/ClonePerformanceTest.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using NUnit.Framework; -namespace Unidux.Test +namespace Unidux.Performance { public class ClonePerformanceTest { @@ -48,10 +48,10 @@ public static SampleState Create(int loop) return state; } -// public override TValue Clone() + // custom implementation of Clone is faster than default BinaryFormatter implementation. +// public override object Clone() // { -// object clonee = CustomClone(); -// return (TValue)clonee; +// return CustomClone(); // } public SampleState CustomClone()