{"action":"created","issue":{"url":"https://api.github.com/repos/ceylon/ceylon/issues/5964","labels_url":"https://api.github.com/repos/ceylon/ceylon/issues/5964/labels{/name}","comments_url":"https://api.github.com/repos/ceylon/ceylon/issues/5964/comments","events_url":"https://api.github.com/repos/ceylon/ceylon/issues/5964/events","html_url":"https://github.com/ceylon/ceylon/issues/5964","id":130016282,"number":5964,"title":"optimize isIdentifiable() and equals() everywhere","user":{"login":"jvasileff","id":236050,"avatar_url":"https://avatars.githubusercontent.com/u/236050?v=3","gravatar_id":"","url":"https://api.github.com/users/jvasileff","html_url":"https://github.com/jvasileff","followers_url":"https://api.github.com/users/jvasileff/followers","following_url":"https://api.github.com/users/jvasileff/following{/other_user}","gists_url":"https://api.github.com/users/jvasileff/gists{/gist_id}","starred_url":"https://api.github.com/users/jvasileff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jvasileff/subscriptions","organizations_url":"https://api.github.com/users/jvasileff/orgs","repos_url":"https://api.github.com/users/jvasileff/repos","events_url":"https://api.github.com/users/jvasileff/events{/privacy}","received_events_url":"https://api.github.com/users/jvasileff/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ceylon/ceylon/labels/m-compiler-java","name":"m-compiler-java","color":"00aa00"},{"url":"https://api.github.com/repos/ceylon/ceylon/labels/t-optimization","name":"t-optimization","color":"006b75"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/ceylon/ceylon/milestones/14","html_url":"https://github.com/ceylon/ceylon/milestones/1.2.2","labels_url":"https://api.github.com/repos/ceylon/ceylon/milestones/14/labels","id":1497228,"number":14,"title":"1.2.2","description":"","creator":{"login":"FroMage","id":179265,"avatar_url":"https://avatars.githubusercontent.com/u/179265?v=3","gravatar_id":"","url":"https://api.github.com/users/FroMage","html_url":"https://github.com/FroMage","followers_url":"https://api.github.com/users/FroMage/followers","following_url":"https://api.github.com/users/FroMage/following{/other_user}","gists_url":"https://api.github.com/users/FroMage/gists{/gist_id}","starred_url":"https://api.github.com/users/FroMage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FroMage/subscriptions","organizations_url":"https://api.github.com/users/FroMage/orgs","repos_url":"https://api.github.com/users/FroMage/repos","events_url":"https://api.github.com/users/FroMage/events{/privacy}","received_events_url":"https://api.github.com/users/FroMage/received_events","type":"User","site_admin":false},"open_issues":127,"closed_issues":5,"state":"open","created_at":"2016-01-11T13:38:44Z","updated_at":"2016-02-01T11:00:47Z","due_on":null,"closed_at":null},"comments":2,"created_at":"2016-01-30T17:31:56Z","updated_at":"2016-02-01T18:55:18Z","closed_at":null,"body":"Some implementations of `equals()` do not have an optimized check for `===`, for example, [Map.equals()](https://github.com/ceylon/ceylon/blob/99a638288eee7ce5c412be0d3f0f3982474e9061/language/src/ceylon/language/Map.ceylon#L182), and even [HashMap.equals()](https://github.com/ceylon/ceylon-sdk/blob/813200ae5e836e67ecfaeb1077879905bbbb4e4a/source/ceylon/collection/HashMap.ceylon#L517). Presumably this is because of the expense of `is Identifiable` in:\r\n\r\n```ceylon\r\nif (is Identifiable this, is Identifiable that, this === that) {\r\n    return true;\r\n}\r\n```\r\n\r\nsince [isIdentifiable()](https://github.com/ceylon/ceylon/blob/df7004436bc07d00f4d0876d1289935cf7717263/language/runtime/com/redhat/ceylon/compiler/java/Util.java#L97) relies on annotations.\r\n\r\nGiven the significant potential savings of `===`, perhaps we should:\r\n\r\n- Decide that `isIdentifiable()`'s performance is \"good enough\", and start using it, or\r\n- Optimize `isIdentifiable()` with the use of marker interfaces `$CeylonClassOrInterface` and `$Identifiable`, so the check would be `instanceof $Identifiable || !(instanceof $CeylonClassOrInterface)`, or\r\n- Something else?\r\n\r\nOf course, the idea of adding marker interfaces would not be backwards compatible. (Although, using just `$Identifiable` for a time would be compatible and at least optimize the `true` case.)"},"comment":{"url":"https://api.github.com/repos/ceylon/ceylon/issues/comments/178128610","html_url":"https://github.com/ceylon/ceylon/issues/5964#issuecomment-178128610","issue_url":"https://api.github.com/repos/ceylon/ceylon/issues/5964","id":178128610,"user":{"login":"jvasileff","id":236050,"avatar_url":"https://avatars.githubusercontent.com/u/236050?v=3","gravatar_id":"","url":"https://api.github.com/users/jvasileff","html_url":"https://github.com/jvasileff","followers_url":"https://api.github.com/users/jvasileff/followers","following_url":"https://api.github.com/users/jvasileff/following{/other_user}","gists_url":"https://api.github.com/users/jvasileff/gists{/gist_id}","starred_url":"https://api.github.com/users/jvasileff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jvasileff/subscriptions","organizations_url":"https://api.github.com/users/jvasileff/orgs","repos_url":"https://api.github.com/users/jvasileff/repos","events_url":"https://api.github.com/users/jvasileff/events{/privacy}","received_events_url":"https://api.github.com/users/jvasileff/received_events","type":"User","site_admin":false},"created_at":"2016-02-01T18:55:18Z","updated_at":"2016-02-01T18:55:18Z","body":"Having just implemented this for Dart, I think the most natural markers are:\r\n\r\n- `$Object`: applied when extending `Object`\r\n- `$Identifiable satisfies $Object`: applied when `Identifiable` is explicitly satisfied\r\n- `$Basic satisfies $Identifiable`: applied when extending `Basic` (implicitly or explicitly), or when extending native classes.\r\n\r\nAlthough, on the JVM, perhaps `.com.redhat.ceylon.compiler.java.runtime.model.ReifiedType` should be used instead of `$Object` if it's already ubiquitous."}}