{"action":"created","issue":{"url":"https://api.github.com/repos/gambit/gambit/issues/214","repository_url":"https://api.github.com/repos/gambit/gambit","labels_url":"https://api.github.com/repos/gambit/gambit/issues/214/labels{/name}","comments_url":"https://api.github.com/repos/gambit/gambit/issues/214/comments","events_url":"https://api.github.com/repos/gambit/gambit/issues/214/events","html_url":"https://github.com/gambit/gambit/issues/214","id":184350425,"number":214,"title":"Suggested new coding expansion for + and -","user":{"login":"gambiteer","id":1544698,"avatar_url":"https://avatars.githubusercontent.com/u/1544698?v=3","gravatar_id":"","url":"https://api.github.com/users/gambiteer","html_url":"https://github.com/gambiteer","followers_url":"https://api.github.com/users/gambiteer/followers","following_url":"https://api.github.com/users/gambiteer/following{/other_user}","gists_url":"https://api.github.com/users/gambiteer/gists{/gist_id}","starred_url":"https://api.github.com/users/gambiteer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gambiteer/subscriptions","organizations_url":"https://api.github.com/users/gambiteer/orgs","repos_url":"https://api.github.com/users/gambiteer/repos","events_url":"https://api.github.com/users/gambiteer/events{/privacy}","received_events_url":"https://api.github.com/users/gambiteer/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"2016-10-20T21:54:30Z","updated_at":"2016-10-25T18:14:44Z","closed_at":null,"body":"Marc:\r\n\r\nI realized that for the C back end (I don't think for the \"universal\" back end) one can safely expand + to, for example, plus2 in the following:\r\n\r\n```\r\n(define (plus2 a b)\r\n  (declare (standard-bindings)\r\n           (extended-bindings)\r\n           (not safe))\r\n  (if (and (fixnum? a)\r\n           (fixnum? b))\r\n      (let ((temp (##fx+? a b)))\r\n        (if temp\r\n            temp\r\n            (let ((big-a (##fixnum->bignum a))\r\n                  (big-b (##fixnum->bignum b)))\r\n              (##bignum.adigit-add! big-a 0 big-b 0 0)\r\n              big-a)))\r\n      (if (and (flonum? a)\r\n               (flonum? b))\r\n          (fl+ a b)\r\n          (+ a b))))\r\n```\r\nYou don't need to call bignum.+ because you don't need the carry propagation (there can't be any) or the normalization (you know the result is a bignum, because ##fx+? returned #f).  This is much faster in the fixnum+fixnum->bignum case, e.g., with\r\n```\r\n(define (plus a b)\r\n  (declare (standard-bindings))\r\n  (+ a b))\r\n\r\n(define (plus2 a b)\r\n  (declare (standard-bindings)\r\n           (extended-bindings)\r\n           (not safe))\r\n  (if (and (fixnum? a)\r\n           (fixnum? b))\r\n      (let ((temp (##fx+? a b)))\r\n        (if temp\r\n            temp\r\n            (let ((big-a (##fixnum->bignum a))\r\n                  (big-b (##fixnum->bignum b)))\r\n              (##bignum.adigit-add! big-a 0 big-b 0 0)\r\n              big-a)))\r\n      (if (and (flonum? a)\r\n               (flonum? b))\r\n          (fl+ a b)\r\n          (+ a b))))\r\n\r\n(define (test a b n)\r\n  (declare (standard-bindings)\r\n           (extended-bindings)\r\n           (not safe))\r\n  (time\r\n   (do ((i 0 (fx+ i 1)))\r\n       ((fx= i n))\r\n     (plus a b)))\r\n  (time\r\n   (do ((i 0 (fx+ i 1)))\r\n       ((fx= i n))\r\n     (plus2 a b ))))\r\n```\r\nyou get on my machine:\r\n```\r\n> (load \"test-plus\")                                  \r\n\"/home/lucier/test-plus.o7\"\r\n> (test ##max-fixnum ##max-fixnum 1000000)            \r\n(time (do ((i 0 (fx+ i 1))) ((fx= i n)) (plus a b)))\r\n    59 ms real time\r\n    60 ms cpu time (56 user, 4 system)\r\n    1 collection accounting for 1 ms real time (4 user, 0 system)\r\n    112000144 bytes allocated\r\n    14409 minor faults\r\n    no major faults\r\n(time (do ((i 0 (fx+ i 1))) ((fx= i n)) (plus2 a b)))\r\n    8 ms real time\r\n    8 ms cpu time (4 user, 4 system)\r\n    no collections\r\n    64000000 bytes allocated\r\n    7883 minor faults\r\n    no major faults\r\n> (test ##max-fixnum ##max-fixnum 10000000)\r\n(time (do ((i 0 (fx+ i 1))) ((fx= i n)) (plus a b)))\r\n    462 ms real time\r\n    460 ms cpu time (460 user, 0 system)\r\n    11 collections accounting for 10 ms real time (8 user, 0 system)\r\n    1120000048 bytes allocated\r\n    3207 minor faults\r\n    no major faults\r\n(time (do ((i 0 (fx+ i 1))) ((fx= i n)) (plus2 a b)))\r\n    48 ms real time\r\n    48 ms cpu time (48 user, 0 system)\r\n    7 collections accounting for 7 ms real time (8 user, 0 system)\r\n    640000000 bytes allocated\r\n    no minor faults\r\n    no major faults\r\n```\r\nalmost a factor of 10.\r\n\r\nIt doesn't work on the universal back end because you don't know that a single adigit can hold twice any fixnum.\r\n\r\nI don't know how often this might come up."},"comment":{"url":"https://api.github.com/repos/gambit/gambit/issues/comments/256117236","html_url":"https://github.com/gambit/gambit/issues/214#issuecomment-256117236","issue_url":"https://api.github.com/repos/gambit/gambit/issues/214","id":256117236,"user":{"login":"gambiteer","id":1544698,"avatar_url":"https://avatars.githubusercontent.com/u/1544698?v=3","gravatar_id":"","url":"https://api.github.com/users/gambiteer","html_url":"https://github.com/gambiteer","followers_url":"https://api.github.com/users/gambiteer/followers","following_url":"https://api.github.com/users/gambiteer/following{/other_user}","gists_url":"https://api.github.com/users/gambiteer/gists{/gist_id}","starred_url":"https://api.github.com/users/gambiteer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gambiteer/subscriptions","organizations_url":"https://api.github.com/users/gambiteer/orgs","repos_url":"https://api.github.com/users/gambiteer/repos","events_url":"https://api.github.com/users/gambiteer/events{/privacy}","received_events_url":"https://api.github.com/users/gambiteer/received_events","type":"User","site_admin":false},"created_at":"2016-10-25T18:14:44Z","updated_at":"2016-10-25T18:14:44Z","body":"On 10/24/2016 03:20 PM, Marc Feeley wrote:\n> Yes... but just to be sure... what you are saying is that one of the\n> four combinations is impossible:\n>\n> |___SCMOBJ_WIDTH==32 ___BIG_ABASE_WIDTH==32 possible ___SCMOBJ_WIDTH==32\n> ___BIG_ABASE_WIDTH==64 possible ___SCMOBJ_WIDTH==64\n> ___BIG_ABASE_WIDTH==32 impossible ___SCMOBJ_WIDTH==64\n> ___BIG_ABASE_WIDTH==64 possible |\n>\n> so gambit.h should not handle the ___SCMOBJ_WIDTH==64\n> ___BIG_ABASE_WIDTH==32 case. Right?\n\nYes.  I'm also concerned about BIGASTORE used in so many places that \ndon't have anything to do with bignums.  That threw me off when I \nstarted looking into macros for doing more fixnum/bignum arithmetic inline.\n\nBrad\n\n"}}
{"actor":{"display_login":"gambiteer"}}