@@ -17,19 +17,7 @@ class BenchmarkItemsPage extends StatelessWidget {
1717 Widget build (BuildContext context) {
1818 const content = BenchmarkItemsWidget ();
1919
20- final addButton = FloatingActionButton (
21- onPressed: () {
22- BenchmarkItem .create ('Latency test ${itemIndex ++}' );
23- },
24- tooltip: 'Create Item' ,
25- child: const Icon (Icons .add),
26- );
27-
28- final page = MyHomePage (
29- title: 'Benchmarks' ,
30- content: content,
31- floatingActionButton: addButton,
32- );
20+ const page = MyHomePage (title: 'Benchmarks' , content: content);
3321 return page;
3422 }
3523}
@@ -49,22 +37,33 @@ class _BenchmarkItemsWidgetState extends State<BenchmarkItemsWidget> {
4937 StreamSubscription ? _subscription;
5038 StreamSubscription ? _countSubscription;
5139 StreamSubscription ? _syncStatusSubscription;
40+ String _latencyString = '0' ;
5241 int ? count;
5342
5443 _BenchmarkItemsWidgetState ();
5544
5645 @override
5746 void initState () {
5847 super .initState ();
59- final stream = BenchmarkItem .watchItems ();
60- _subscription = stream.listen ((data) {
48+ _subscription = BenchmarkItem .watchGroupedItems ().listen ((data) {
6149 if (! context.mounted) {
6250 return ;
6351 }
52+
53+ // Latency is the same for all items in the group
54+ final latencies =
55+ data.map ((e) => e.latency).where ((e) => e != null ).toList ();
56+ final totalLatency = latencies.fold (0 , (a, b) => a + b! .inMicroseconds);
57+ final averageLatencyMicros =
58+ latencies.isNotEmpty ? totalLatency / latencies.length : 0 ;
59+ final latencyString = (averageLatencyMicros / 1000.0 ).toStringAsFixed (1 );
60+
6461 setState (() {
6562 _data = data;
63+ _latencyString = latencyString;
6664 });
6765 });
66+
6867 _countSubscription =
6968 db.watch ('select count() as count from ps_oplog' ).listen ((data) {
7069 if (! context.mounted) {
@@ -92,6 +91,20 @@ class _BenchmarkItemsWidgetState extends State<BenchmarkItemsWidget> {
9291 _countSubscription? .cancel ();
9392 }
9493
94+ Future <void > createBatch (int n) async {
95+ var items = < String > [];
96+ for (var i = 1 ; i <= n; i++ ) {
97+ items.add ('Batch Test $itemIndex /$i ' );
98+ }
99+ itemIndex += 1 ;
100+ await db.execute ('''
101+ INSERT INTO
102+ benchmark_items(id, description, client_created_at)
103+ SELECT uuid(), e.value, datetime('now', 'subsecond') || 'Z'
104+ FROM json_each(?) e
105+ ''' , [jsonEncode (items)]);
106+ }
107+
95108 @override
96109 Widget build (BuildContext context) {
97110 Duration ? syncDuration = timer.syncTime ?? timer.elapsed;
@@ -101,13 +114,6 @@ class _BenchmarkItemsWidgetState extends State<BenchmarkItemsWidget> {
101114 "Busy with sync... ${syncDuration .inMilliseconds }ms / $count operations" ));
102115 }
103116
104- final latencies =
105- _data.map ((e) => e.latency).where ((e) => e != null ).toList ();
106- final totalLatency = latencies.fold (0 , (a, b) => a + b! .inMicroseconds);
107- final averageLatencyMicros =
108- latencies.isNotEmpty ? totalLatency / latencies.length : 0 ;
109- final latencyString = (averageLatencyMicros / 1000.0 ).toStringAsFixed (1 );
110-
111117 final clearButton = TextButton .icon (
112118 label: const Text ('Delete all' ),
113119 onPressed: () {
@@ -122,37 +128,24 @@ class _BenchmarkItemsWidgetState extends State<BenchmarkItemsWidget> {
122128 },
123129 icon: const Icon (Icons .sync ));
124130
131+ final create1 = TextButton .icon (
132+ label: const Text ('+1' ),
133+ onPressed: () async {
134+ await createBatch (1 );
135+ },
136+ icon: const Icon (Icons .create));
137+
125138 final create100 = TextButton .icon (
126- label: const Text ('Create 100' ),
139+ label: const Text ('+ 100' ),
127140 onPressed: () async {
128- var items = < String > [];
129- for (var i = 1 ; i <= 100 ; i++ ) {
130- items.add ('Batch Test $itemIndex /$i ' );
131- }
132- itemIndex += 1 ;
133- await db.execute ('''
134- INSERT INTO
135- benchmark_items(id, description, client_created_at)
136- SELECT uuid(), e.value, datetime('now', 'subsecond') || 'Z'
137- FROM json_each(?) e
138- ''' , [jsonEncode (items)]);
141+ await createBatch (100 );
139142 },
140143 icon: const Icon (Icons .create));
141144
142145 final create1000 = TextButton .icon (
143- label: const Text ('Create 1000' ),
146+ label: const Text ('+ 1000' ),
144147 onPressed: () async {
145- var items = < String > [];
146- for (var i = 1 ; i <= 1000 ; i++ ) {
147- items.add ('Batch Test $itemIndex /$i ' );
148- }
149- itemIndex += 1 ;
150- await db.execute ('''
151- INSERT INTO
152- benchmark_items(id, description, client_created_at)
153- SELECT uuid(), e.value, datetime('now', 'subsecond') || 'Z'
154- FROM json_each(?) e
155- ''' , [jsonEncode (items)]);
148+ await createBatch (1000 );
156149 },
157150 icon: const Icon (Icons .create));
158151
@@ -164,7 +157,8 @@ class _BenchmarkItemsWidgetState extends State<BenchmarkItemsWidget> {
164157 overflowSpacing: 8.0 ,
165158 children: < Widget > [
166159 Text (
167- 'First sync duration: ${syncDuration .inMilliseconds }ms / $count operations / ${latencyString }ms latency' ),
160+ 'First sync duration: ${syncDuration .inMilliseconds }ms / $count operations / ${_latencyString }ms latency' ),
161+ create1,
168162 create100,
169163 create1000,
170164 resyncButton,
0 commit comments