{ "id": "174883", "key": "AC-6521", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false }, "project": { "id": "12217", "key": "AC", "name": "Appcelerator - INBOX", "projectCategory": { "id": "10000", "description": "", "name": "Customer Service" } }, "resolution": { "id": "10000", "description": "", "name": "Done" }, "resolutiondate": "2020-04-17T18:16:34.000+0000", "created": "2020-04-04T18:21:49.000+0000", "labels": [ "android", "performance", "test" ], "versions": [], "issuelinks": [], "assignee": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2020-04-17T18:16:34.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [], "description": "I was doing some tests with the SDK (e.g. optimizing some many for-loops and some keySet() -> entryMap() changes) and was looking to find some performance tests. I found and old page from shockoe where they did some performance testing. I used that code \r\n{code}\r\n// Proxy creation - Sequential Sets\r\nfunction createViews() {\r\n\tvar theWindow = Ti.UI.createWindow({\r\n\t\tlayout: 'vertical'\r\n\t});\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newView = Ti.UI.createView();\r\n\r\n\t\t\tnewView.top = 5;\r\n\t\t\tnewView.height = 40;\r\n\t\t\tnewView.width = Ti.UI.FILL;\r\n\t\t\tnewView.left = 5;\r\n\t\t\tnewView.right = 5;\r\n\t\t\tnewView.backgroundColor = 'red';\r\n\r\n\t\t\ttheWindow.add(newView);\r\n\t\t}\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('added 1000 views w/o/ creation dict in ' + delta + 'ms');\r\n\t\tcreateViewsWithDict()\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n\r\n\r\n// Proxy creation - Creation dict\r\n\r\nfunction createViewsWithDict() {\r\n\tvar theWindow = Ti.UI.createWindow({\r\n\t\tlayout: 'vertical'\r\n\t});\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newView = Ti.UI.createView({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttheWindow.add(newView);\r\n\t\t}\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('added 1000 views w/ creation dict in ' + delta + 'ms');\r\n\t\tupdateViews();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n// Proxy update - Sequential Sets\r\n\r\nfunction updateViews() {\r\n\tvar theWindow = Ti.UI.createWindow({\r\n\t\tlayout: 'vertical'\r\n\t});\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newView = Ti.UI.createView({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttheWindow.add(newView);\r\n\t\t}\r\n\r\n\t\tvar children = theWindow.children;\r\n\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tchildren[ii].height = 80;\r\n\t\t\tchildren[ii].backgroundColor = 'blue';\r\n\t\t\tchildren[ii].left = 10;\r\n\t\t\tchildren[ii].right = 10;\r\n\t\t}\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('updated 1000 views sequentially in ' + delta + 'ms');\r\n\t\tupdateViewsApplyProperties();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\nfunction updateViewsApplyProperties() {\r\n\tvar theWindow = Ti.UI.createWindow({\r\n\t\tlayout: 'vertical'\r\n\t});\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newView = Ti.UI.createView({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttheWindow.add(newView);\r\n\t\t}\r\n\r\n\t\tvar children = theWindow.children;\r\n\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tchildren[ii].applyProperties({\r\n\t\t\t\theight: 80,\r\n\t\t\t\tbackgroundColor: 'blue',\r\n\t\t\t\tleft: 10,\r\n\t\t\t\tright: 10\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('updated 1000 views via applyProperties in ' + delta + 'ms');\r\n\t\tcreateViewsWithDict();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n\r\n\r\n// Proxy creation - Creation dict\r\n\r\nfunction createViewsWithDict() {\r\n\tvar theWindow = Ti.UI.createWindow({\r\n\t\tlayout: 'vertical'\r\n\t});\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newView = Ti.UI.createView({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttheWindow.add(newView);\r\n\t\t}\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('added 1000 views w/ creation dict in ' + delta + 'ms');\r\n\t\tpopulateTableViewSequential();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n\r\n\r\n// Table population - sequential\r\nfunction populateTableViewSequential() {\r\n\tvar theWindow = Ti.UI.createWindow();\r\n\r\n\tvar theTable = Ti.UI.createTableView({\r\n\t\twidth: Ti.UI.FILL,\r\n\t\theight: Ti.UI.FILL\r\n\t});\r\n\r\n\ttheWindow.add(theTable);\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newRow = Ti.UI.createTableViewRow({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttheTable.appendRow(newRow);\r\n\t\t}\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('added 1000 rows sequentially in ' + delta + 'ms');\r\n\t\tpopulateTableViewEnMasse();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n// Table population - bulk\r\nfunction populateTableViewEnMasse() {\r\n\tvar theWindow = Ti.UI.createWindow();\r\n\r\n\tvar theTable = Ti.UI.createTableView({\r\n\t\twidth: Ti.UI.FILL,\r\n\t\theight: Ti.UI.FILL\r\n\t});\r\n\r\n\ttheWindow.add(theTable);\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tvar tableData = [];\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newRow = Ti.UI.createTableViewRow({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttableData.push(newRow);\r\n\t\t}\r\n\r\n\t\ttheTable.data = tableData;\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('added 1000 rows en masse in ' + delta + 'ms');\r\n\t\tremoveViews();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n\r\n// View removal - sequential\r\n\r\nfunction removeViews() {\r\n\tvar theWindow = Ti.UI.createWindow({\r\n\t\tlayout: 'vertical'\r\n\t});\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newView = Ti.UI.createView({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttheWindow.add(newView);\r\n\t\t}\r\n\r\n\t\tvar startTime = new Date();\r\n\r\n\t\tvar children = theWindow.children;\r\n\r\n\t\tfor (var ii = 0, numChildren = children.length; ii < numChildren; ++ii) {\r\n\t\t\ttheWindow.remove(children[ii]);\r\n\t\t}\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('removed 1000 views in ' + delta + 'ms');\r\n\t\tremoveViewsEnMasse();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n// View removal - bulk\r\n\r\nfunction removeViewsEnMasse() {\r\n\tvar theWindow = Ti.UI.createWindow({\r\n\t\tlayout: 'vertical'\r\n\t});\r\n\r\n\ttheWindow.addEventListener('open', function() {\r\n\r\n\t\tfor (var ii = 0; ii < 1000; ++ii) {\r\n\t\t\tvar newView = Ti.UI.createView({\r\n\t\t\t\ttop: 5,\r\n\t\t\t\theight: 40,\r\n\t\t\t\twidth: Ti.UI.FILL,\r\n\t\t\t\tleft: 5,\r\n\t\t\t\tright: 5,\r\n\t\t\t\tbackgroundColor: 'red'\r\n\t\t\t});\r\n\r\n\t\t\ttheWindow.add(newView);\r\n\t\t}\r\n\r\n\t\tvar startTime = new Date();\r\n\r\n\t\ttheWindow.removeAllChildren();\r\n\r\n\t\tvar endTime = new Date();\r\n\t\tvar delta = endTime - startTime;\r\n\r\n\t\ttheWindow.close();\r\n\r\n\t\tconsole.log('removed 1000 views en masse in ' + delta + 'ms');\r\n\t\teventFiringTitanium();\r\n\t});\r\n\r\n\ttheWindow.open();\r\n}\r\n\r\n//Events - Ti.App events\r\n\r\nfunction eventFiringTitanium() {\r\n\tvar startTime;\r\n\r\n\tvar handledCount = 0;\r\n\r\n\tfunction testListener() {\r\n\t\thandledCount++;\r\n\r\n\t\tif (handledCount === 10000) {\r\n\t\t\tvar endTime = new Date();\r\n\t\t\tvar delta = endTime - startTime;\r\n\r\n\t\t\tconsole.log('fired 10000 Ti.APP events in ' + delta + 'ms');\r\n\r\n\t\t\tTi.App.removeEventListener('testEvent', testListener);\r\n\t\t\teventFiringBackbone();\r\n\t\t}\r\n\t}\r\n\r\n\tTi.App.addEventListener('testEvent', testListener);\r\n\r\n\tstartTime = new Date();\r\n\r\n\tfor (var ii = 0; ii < 10000; ++ii) {\r\n\t\tTi.App.fireEvent('testEvent');\r\n\t}\r\n}\r\n\r\n//Events - Backbone\r\nfunction eventFiringBackbone() {\r\n\tvar startTime;\r\n\r\n\t//since events fire asynchronously, we need to keep track of how many were handled.\r\n\tvar handledCount = 0;\r\n\tvar eventingObj = _.extend({}, Backbone.Events);\r\n\r\n\teventingObj.on('testEvent', function() {\r\n\t\thandledCount++;\r\n\r\n\t\tif (handledCount === 10000) {\r\n\t\t\tvar endTime = new Date();\r\n\t\t\tvar delta = endTime - startTime;\r\n\r\n\t\t\tconsole.log('fired 10000 Backbone events in ' + delta + 'ms');\r\n\t\t}\r\n\t});\r\n\r\n\tstartTime = new Date();\r\n\r\n\tfor (var ii = 0; ii < 10000; ++ii) {\r\n\t\teventingObj.trigger('testEvent');\r\n\t}\r\n}\r\n\r\nvar w = Ti.UI.createWindow({});\r\nw.addEventListener(\"open\", function() {\r\n\tcreateViews();\r\n})\r\nw.open();\r\n{code}\r\n\r\nIt looks like 9.0.0.GA got slower in some parts.\r\n\r\n*8.3.1.GA:*\r\nadded 1000 views w/o/ creation dict in 1229ms\r\nadded 1000 views w/ creation dict in 1206ms\r\nadded 1000 rows sequentially in 1796ms\r\nadded 1000 rows en masse in 1187ms\r\nremoved 1000 views in 61ms\r\nremoved 1000 views en masse in 21ms\r\nfired 10000 Ti.APP events in 99ms\r\nfired 10000 Backbone events in 44ms\r\n\r\n*9.0.0.GA:*\r\nadded 1000 views w/o/ creation dict in 2364ms\r\nadded 1000 views w/ creation dict in 2077ms\r\nadded 1000 rows sequentially in 2414ms\r\nadded 1000 rows en masse in 1626ms\r\nremoved 1000 views in 369ms\r\nremoved 1000 views en masse in 21ms\r\nfired 10000 Ti.APP events in 148ms\r\nfired 10000 Backbone events in 46ms\r\n\r\nAre there any other performance tests for more options/tests? \r\nWhy are the view creation numbers slower?", "attachment": [], "flagged": false, "summary": "Android view performance tests slower with 9.0.0.GA", "creator": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "environment": null, "comment": { "comments": [ { "id": "454998", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "As of Titanium 9.0.0, we now build a \"debug\" version of the APK when your deployment type is \"development\" or \"test\". This is new and will cause the app to be a bit slower at runtime.\r\n\r\nIf you build for \"production\", then Titanium 9.0.0 will build a \"release\" version of the APK like before. This will provide the faster results you are looking for.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-04-07T02:37:52.000+0000", "updated": "2020-04-07T02:38:16.000+0000" }, { "id": "455093", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "I see. Thanks for the hint! Here are the production numbers:\r\n\r\n*8.3.1.GA*\r\nadded 1000 views w/o/ creation dict in 378ms\r\nadded 1000 views w/ creation dict in 359ms\r\nadded 1000 rows sequentially in 486ms\r\nadded 1000 rows en masse in 303ms\r\nremoved 1000 views in 10ms\r\nremoved 1000 views en masse in 6ms\r\nfired 10000 Ti.APP events in 19ms\r\nfired 10000 Backbone events in 9ms\r\n\r\n*9.0.0.GA*\r\nadded 1000 views w/o/ creation dict in 406ms\r\nadded 1000 views w/ creation dict in 378ms\r\nadded 1000 rows sequentially in 606ms\r\nadded 1000 rows en masse in 315ms\r\nremoved 1000 views in 43ms\r\nremoved 1000 views en masse in 3ms\r\nfired 10000 Ti.APP events in 20ms\r\nfired 10000 Backbone events in 10ms\r\n\r\ncan be closed :)", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-04-12T19:31:54.000+0000", "updated": "2020-04-12T19:31:54.000+0000" } ], "maxResults": 2, "total": 2, "startAt": 0 } } }