{"action":"created","issue":{"url":"https://api.github.com/repos/angular/angular.js/issues/11099","labels_url":"https://api.github.com/repos/angular/angular.js/issues/11099/labels{/name}","comments_url":"https://api.github.com/repos/angular/angular.js/issues/11099/comments","events_url":"https://api.github.com/repos/angular/angular.js/issues/11099/events","html_url":"https://github.com/angular/angular.js/issues/11099","id":58071409,"number":11099,"title":"angular.copy Very poor performance (large objects)","user":{"login":"Tomino2112","id":1140217,"avatar_url":"https://avatars.githubusercontent.com/u/1140217?v=3","gravatar_id":"","url":"https://api.github.com/users/Tomino2112","html_url":"https://github.com/Tomino2112","followers_url":"https://api.github.com/users/Tomino2112/followers","following_url":"https://api.github.com/users/Tomino2112/following{/other_user}","gists_url":"https://api.github.com/users/Tomino2112/gists{/gist_id}","starred_url":"https://api.github.com/users/Tomino2112/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tomino2112/subscriptions","organizations_url":"https://api.github.com/users/Tomino2112/orgs","repos_url":"https://api.github.com/users/Tomino2112/repos","events_url":"https://api.github.com/users/Tomino2112/events{/privacy}","received_events_url":"https://api.github.com/users/Tomino2112/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/angular/angular.js/labels/component:%20misc%20core","name":"component: misc core","color":"fef2c0"},{"url":"https://api.github.com/repos/angular/angular.js/labels/type:%20perf","name":"type: perf","color":"207de5"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/angular/angular.js/milestones/38","html_url":"https://github.com/angular/angular.js/milestones/Ice%20Box","labels_url":"https://api.github.com/repos/angular/angular.js/milestones/38/labels","id":529901,"number":38,"title":"Ice Box","description":"Milestone for valid issues and bugs that we have no aspirations on fixing any time soon because they are not affecting primary use-cases and are not aligned with our goals.","creator":{"login":"IgorMinar","id":216296,"avatar_url":"https://avatars.githubusercontent.com/u/216296?v=3","gravatar_id":"","url":"https://api.github.com/users/IgorMinar","html_url":"https://github.com/IgorMinar","followers_url":"https://api.github.com/users/IgorMinar/followers","following_url":"https://api.github.com/users/IgorMinar/following{/other_user}","gists_url":"https://api.github.com/users/IgorMinar/gists{/gist_id}","starred_url":"https://api.github.com/users/IgorMinar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IgorMinar/subscriptions","organizations_url":"https://api.github.com/users/IgorMinar/orgs","repos_url":"https://api.github.com/users/IgorMinar/repos","events_url":"https://api.github.com/users/IgorMinar/events{/privacy}","received_events_url":"https://api.github.com/users/IgorMinar/received_events","type":"User","site_admin":false},"open_issues":179,"closed_issues":136,"state":"open","created_at":"2014-01-08T08:19:21Z","updated_at":"2015-10-27T18:25:14Z","due_on":null,"closed_at":null},"comments":27,"created_at":"2015-02-18T14:05:13Z","updated_at":"2015-10-27T19:08:05Z","closed_at":null,"body":"Our application loads resources from API and renders them in a table. API request takes ~200ms, rendering table ~140ms but when you actually looking at the page it takes about 6s to display it.\r\n\r\nI have drilled through the code and realized this was caused by using angular.copy . I need to keep track of the old data so I copied the whole object to backup object via angular.copy() function. The copying itself took over 2s (~2500ms). \r\n\r\nI have searched for better ways, to copy objects and stumbled upon this code: \r\n\r\n```\r\ncloneObject: function(o){\r\n            const gdcc = \"__getDeepCircularCopy__\";\r\n            if (o !== Object(o)) {\r\n                return o; // primitive value\r\n            }\r\n\r\n            var set = gdcc in o,\r\n                cache = o[gdcc],\r\n                result;\r\n            if (set && typeof cache == \"function\") {\r\n                return cache();\r\n            }\r\n            // else\r\n            o[gdcc] = function() { return result; }; // overwrite\r\n            if (o instanceof Array) {\r\n                result = [];\r\n                for (var i=0; i<o.length; i++) {\r\n                    result[i] = this.cloneObject(o[i]);\r\n                }\r\n            } else {\r\n                result = {};\r\n                for (var prop in o)\r\n                    if (prop != gdcc)\r\n                        result[prop] = this.cloneObject(o[prop]);\r\n                    else if (set)\r\n                        result[prop] = this.cloneObject(cache);\r\n            }\r\n            if (set) {\r\n                o[gdcc] = cache; // reset\r\n            } else {\r\n                delete o[gdcc]; // unset again\r\n            }\r\n            return result;\r\n        },\r\n```\r\nThis is my implementation of this: http://stackoverflow.com/a/10729242/820942\r\n\r\nReplacing all angular.copy() in my code with this **hugely** improved the webapp overall. The same example above takes ~41ms instead of ~2s. \r\n\r\nI should mention that the data I am mentioning is pretty large (renders into 10 000 cells table)\r\n\r\nAfter very brief look on the angular.copy code I am aware of that there are some added angular goodies ($$hashkey) but still the difference in performance is just too big."},"comment":{"url":"https://api.github.com/repos/angular/angular.js/issues/comments/151612980","html_url":"https://github.com/angular/angular.js/issues/11099#issuecomment-151612980","issue_url":"https://api.github.com/repos/angular/angular.js/issues/11099","id":151612980,"user":{"login":"frfancha","id":9610263,"avatar_url":"https://avatars.githubusercontent.com/u/9610263?v=3","gravatar_id":"","url":"https://api.github.com/users/frfancha","html_url":"https://github.com/frfancha","followers_url":"https://api.github.com/users/frfancha/followers","following_url":"https://api.github.com/users/frfancha/following{/other_user}","gists_url":"https://api.github.com/users/frfancha/gists{/gist_id}","starred_url":"https://api.github.com/users/frfancha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/frfancha/subscriptions","organizations_url":"https://api.github.com/users/frfancha/orgs","repos_url":"https://api.github.com/users/frfancha/repos","events_url":"https://api.github.com/users/frfancha/events{/privacy}","received_events_url":"https://api.github.com/users/frfancha/received_events","type":"User","site_admin":false},"created_at":"2015-10-27T19:08:05Z","updated_at":"2015-10-27T19:08:05Z","body":"@jbedard Ok thanks for the info. We will try 1.5 then, I'm very curious about the performance difference. I hope there won't be too many breaking changes in 1.5"}}