ReactiveProperty v7.8.0 をリリースしました

2 min読了の目安(約2600字TECH技術記事

ReactiveProperty v7.8.0 をリリースしました。
今回は Issue で報告のあった FilteredReadOnlyObservableCollection の性能改善と、それに付随する関連メソッドの性能改善になります。
具体的には以下のメソッドの性能改善及び挙動が変更になっています。

  • PropertyChangedAsObservable
  • CollectionChangedAsObservable
  • CanExecuteChangedAsObservable
  • ErrorsChangedAsObservable

上記メソッドは、以下のメソッドからも参照されているので、以下のメソッドについても性能改善および挙動の変更があります。

  • ObserveProperty
  • Observe(Add|Remove|Move|Replace|Reset)Changed
  • Observe(Add|Remove|Move|Replace)ChangedItems
  • ReadOnlyReactiveCollection
  • ObserveElementProperty
  • ObserveElementObservableProperty
  • ObserveErrorInfo
  • FilteredReadOnlyObservableCollection

計測結果

性能改善前と回前後で ObserveProperty のベンチマークをとりました。

性能改善前

Method Count Mean Error StdDev
ObserveProperty 1 4.662 us 0.0403 us 0.0377 us
ObserveProperty 10 46.159 us 0.2482 us 0.2322 us
ObserveProperty 100 488.395 us 3.9745 us 3.7177 us
ObserveProperty 1000 7,299.851 us 49.5364 us 41.3651 us
ObserveProperty 10000 184,803.556 us 2,443.4350 us 2,285.5906 us
ObserveProperty 100000 21,848,008.562 us 183,192.5623 us 152,974.0864 us

性能改善後

Method Count Mean Error StdDev
ObserveProperty 1 3.313 us 0.0226 us 0.0200 us
ObserveProperty 10 32.927 us 0.2260 us 0.2114 us
ObserveProperty 100 335.572 us 2.0898 us 1.9548 us
ObserveProperty 1000 4,245.384 us 82.0820 us 91.2340 us
ObserveProperty 10000 79,851.266 us 1,057.3668 us 937.3281 us
ObserveProperty 100000 779,906.493 us 8,120.6971 us 7,596.1051 us

数が増えると大幅に性能に差が出てることがわかります。

動作について

この性能改善により以下の挙動が変わっています。

変更前

PropertyChangedAsObservableObserveProperty では SynchronizationContext があるスレッドで Subscribe を行うと自動的に Subscribe を呼び出したスレッドで OnNext などの処理が呼ばれます。
なので、WPF や UWP や Xamarin.Forms などの UI スレッド上で Subscribe を行っていると自動的に UI スレッドで Subscribe が呼び出されていました。

変更後

SynchronizationContext があるスレッドで Subscribe を行っても OnNext などは自動的にスレッドが切り替わることはありません。
イベントが発生したスレッド上で OnNext なども実行されます。

もし、明示的にスレッドを切り替えたい場合は ObserveOnUIDispatcher などを Rx のメソッドチェーン内に含めて手動でスレッドの切替を行ってください。

各種リンク

https://github.com/runceel/ReactiveProperty

https://www.nuget.org/packages/ReactiveProperty/7.8.0