{ "id": "122031", "key": "TIMOB-15756", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": null, "resolutiondate": null, "created": "2013-11-04T18:36:32.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "SupportTeam" ], "versions": [ { "id": "15593", "description": "Release 3.1.3", "name": "Release 3.1.3", "archived": true, "released": true, "releaseDate": "2013-09-18" } ], "issuelinks": [], "assignee": null, "updated": "2018-02-28T20:04:04.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "h4. Problem Description\r\nI just noticed that calling Ti.File.exists() on a file that is missing is quite costly in Android (on Galaxy S4). The folder contains only one file, and I am trying Ti.Filesystem.getFile('wrongfile').exists(). It takes 500-600 ms for this call to complete. In comparison Ti.Filesystem.getFile('wrongfile').getSize() returns 0 immediately.\r\n\r\nh4. Workaround\r\nUse Ti.Filesystem.getFile('wrongfile').getSize() instead of exists\r\n\r\n", "attachment": [], "flagged": false, "summary": "Android: Ti.File.exists() slow performance", "creator": { "name": "vlast3k", "key": "vlast3k", "displayName": "Vladimir S", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "vlast3k", "key": "vlast3k", "displayName": "Vladimir S", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "SDK 3.1.3, Android, Samsung S4", "comment": { "comments": [ { "id": "278129", "author": { "name": "morahman", "key": "morahman", "displayName": "Motiur Rahman", "active": true, "timeZone": "Asia/Dhaka" }, "body": "Hi Vladimir S,\n\nCould you share some simple app.js code so that i reproduce this issue.\n\nThanks,", "updateAuthor": { "name": "morahman", "key": "morahman", "displayName": "Motiur Rahman", "active": true, "timeZone": "Asia/Dhaka" }, "created": "2013-11-05T06:16:07.000+0000", "updated": "2013-11-05T06:16:07.000+0000" }, { "id": "306437", "author": { "name": "philet", "key": "philet", "displayName": "Philippe Wueger", "active": true, "timeZone": "Europe/Berlin" }, "body": "The TiResourceFile exists() method does a directory listing if the file does not exist in order to check if the file is a directory. This directory listing seems to be slow (maybe only on large directories).\r\n\r\nPossible solutions within the Titanium framework:\r\n1. Add an (optional) argument \"checkForDirectories\" to the exists method and only check for directory if really needed\r\n2. Check if there are more efficient solutions to see if a file is an existing directory\r\n\r\n", "updateAuthor": { "name": "philet", "key": "philet", "displayName": "Philippe Wueger", "active": true, "timeZone": "Europe/Berlin" }, "created": "2014-05-27T09:35:36.000+0000", "updated": "2014-05-27T09:35:36.000+0000" }, { "id": "306507", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~philet] Can you give an example of what is slow? What is the difference between a file in a directory with only one file and a directory with 1000 files.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-05-27T18:45:57.000+0000", "updated": "2014-05-27T18:45:57.000+0000" }, { "id": "308250", "author": { "name": "philet", "key": "philet", "displayName": "Philippe Wueger", "active": true, "timeZone": "Europe/Berlin" }, "body": "Hi Ingo\r\n\r\nOn a Galaxy Nexus Phone with SDK 3.2.3 it does not seem to make a difference if a directory with 1000 files is checked or a directory with 1 file. If the file does not exist, it is slow (around ~70ms). If the file exists, it is fast (<1ms).\r\n\r\nSee my code and the results below.\r\n\r\nThanks & Regards,\r\nPhilippe\r\n\r\napp.js\r\n{code}\r\nvar directoryWith1000Files = 'oneFile';\r\nvar directoryWith1File = 'thousandFiles';\r\nvar existingFile = 'i-do-exist.txt';\r\nvar nonExistentFile = 'i-do-not-exist.txt';\r\n\r\nfunction measure(directory, fileName) {\r\n\tfor (var i=0; i < 10; i++) {\r\n\t\tvar file = Ti.Filesystem.getFile(directory, fileName);\r\n\t\tvar t1 = new Date();\r\n\t\tvar result = file.exists();\r\n\t\tvar t2 = new Date();\r\n\t\tTi.API.info(String.format('TIME (ms): %d | %s | %s', t2.getTime() - t1.getTime(), result ? 'EXISTS' : 'DOES NOT EXIST', file.nativePath));\r\n\t};\t\r\n}\r\n\r\nTi.API.info(\"directoryWith1File / existingFile:\");\r\nmeasure(directoryWith1File, existingFile);\r\n\r\nTi.API.info(\"directoryWith1000Files / existingFile:\");\r\nmeasure(directoryWith1000Files, existingFile);\r\n\r\nTi.API.info(\"directoryWith1File / nonExistentFile:\");\r\nmeasure(directoryWith1File, nonExistentFile);\r\n\r\nTi.API.info(\"directoryWith1000Files / nonExistentFile:\");\r\nmeasure(directoryWith1000Files, nonExistentFile);\r\n\r\n{code}\r\n\r\nResults:\r\n{code}\r\n[INFO] : TIME (ms): 3 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/thousandFiles/i-do-exist.txt\r\n[INFO] : directoryWith1000Files / existingFile:\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 1 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 3 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 1 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : TIME (ms): 0 | EXISTS | file:///android_asset/Resources/oneFile/i-do-exist.txt\r\n[INFO] : directoryWith1File / nonExistentFile:\r\n[INFO] : TIME (ms): 88 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 77 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 85 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 72 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 79 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 68 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 66 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 67 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 70 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 66 | DOES NOT EXIST | file:///android_asset/Resources/thousandFiles/i-do-not-exist.txt\r\n[INFO] : directoryWith1000Files / nonExistentFile:\r\n[INFO] : TIME (ms): 66 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 66 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 78 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 70 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 86 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 70 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 67 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 67 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 66 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n[INFO] : TIME (ms): 65 | DOES NOT EXIST | file:///android_asset/Resources/oneFile/i-do-not-exist.txt\r\n{code}", "updateAuthor": { "name": "philet", "key": "philet", "displayName": "Philippe Wueger", "active": true, "timeZone": "Europe/Berlin" }, "created": "2014-06-10T14:55:40.000+0000", "updated": "2014-06-10T14:55:40.000+0000" } ], "maxResults": 4, "total": 4, "startAt": 0 } } }