рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреВрдВрдЫ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдЕрдиреБрдХрд░рдг

рдпрджрд┐ рдХрд┐рд╕реА рдФрд░ рдХреЛ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдкреВрдВрдЫ рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреНрдпрд╛ рд╣реИ, рддреЛ рдпрд╣рд╛рдВ рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ 1 рд╕реЗ n рддрдХ рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдЬреЛрдбрд╝рддрд╛ рд╣реИ (n n0):
function add(n,acc) { if(n===0) return acc; return add(n-1,acc+n); } 

рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдПрд╕реАрд╕реА = 0 рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ n рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╡рд┐рдзрд┐ рдЦреБрдж рдХреЛ рдЕрдиреНрдп рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХреЙрд▓ рдХрд░рддреА рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рддреА рд╣реИред рд╕рдВрдХрд▓рдХ (рдпрд╛ рджреБрднрд╛рд╖рд┐рдпрд╛, рдпрд╛ рдЖрднрд╛рд╕реА рдорд╢реАрди) рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╕реНрдЯреИрдХ рдкрд░ рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреА рдЕрдм рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕реЗ рдорд┐рдЯрд╛ рджреЗрдВ рдФрд░ рдЗрд╕реЗ рдЕрдЧрд▓реА рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕реЗ рдвреЗрд░ рдмрдврд╝рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдирд╣реАрдВ рдмрдирддрд╛ рд╣реИред рдХрдбрд╝рд╛рдИ рд╕реЗ рдмреЛрд▓рддреЗ рд╣реБрдП, рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЯреЗрд▓ рдХреЙрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ: рдХреЛрдИ рднреА рдЕрдиреНрдп рдХреЙрд▓ рднреА рдЯреЗрд▓ рд╣реЛ рд╕рдХрддреА рд╣реИред рдореБрдЦреНрдп рд╕реНрдерд┐рддрд┐: рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдФрд░ рдЙрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЕрдВрддрд┐рдо рдХреНрд░рд┐рдпрд╛рдПрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдкреВрдВрдЫ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЙрд▓ рдХреЗ рдмрд╛рдж рднреА рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рд╣реИ:
 function add(n) { if(n===0) return 0; return n+add(n-1); } 

рдХрдИ рдХрд╛рд░рдгреЛрдВ рд╕реЗ, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдкреВрдВрдЫ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ( рд╕реНрдЯреИрдХрдСрд╡рд░рдлрд╝реНрд▓реЛ рдкрд░ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдЪрд░реНрдЪрд╛ рд╣реЛрддреА рд╣реИ)ред рдЗрд╕рд▓рд┐рдП, рдРрдб (100000.0) рдЬреИрд╕реА рдХреЙрд▓ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрдЧреАред Habr├й рдкрд░ рд╕реЗрдЯрдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ , рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдИрдорд╛рдирджрд╛рд░ рдирд╣реАрдВ рд╣реИ рдФрд░ рдмрд╣реБрдд рд╕реБрдВрджрд░ рдирд╣реАрдВ рд╣реИред рдПрдХ рд╕реНрдкреНрд░рд┐рдВрдЧрдмреЛрд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рдпрдерди рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рди рджреГрд╖реНрдЯрд┐рдХреЛрдг рдпрд╣рд╛рдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╣реИ ред рд▓реЗрдХрд┐рди рдореИрдВ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдЬрд▓реНрджреА рд╕реЗ рдХрд╛рдо рдХрд░реЗ рдФрд░ рдпрд╣ рдХрд╛рд░реНрдп рд╕реАрдзреЗ рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХреЗред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ, рд╣рдо рдПрдХ рд╕реАрдорд┐рдд, рдмрд▓реНрдХрд┐ рд▓реЛрдХрдкреНрд░рд┐рдп рдорд╛рдорд▓реЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдЬрдм рдХреЛрдИ рдлрд╝рдВрдХреНрд╢рди рдХреЗрд╡рд▓ рдкреВрдВрдЫ рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ (рдпрд╣ рдХрд┐рд╕реА рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдирдХреА рдХреЙрд▓ рдЕрдиреБрдХреВрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрдЧреА)ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЖрдкрдХреЛ рдлрд┐рд░ рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдкрдХреЛ рддрд░реНрдХ рдорд╛рдиреЛрдВ рдХреЛ рдирдП рдХреЗ рд╕рд╛рде рдмрджрд▓рдиреЗ рдФрд░ рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдХреЛрдИ рдЧреЛрдЯреЛ рдСрдкрд░реЗрдЯрд░ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рд╣рдореЗрд╢рд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмреНрд▓реЙрдХ рдореЗрдВ рд▓рдкреЗрдЯ рд╕рдХрддреЗ рд╣реИрдВ:
 $tail$label:while(true) { < >; return; } 

рдлрд┐рд░ continue $tail$label рд╣реБрдП рдлрд╝рдВрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЬрд╛рдПрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдВрдХреНрд░рдордг рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЛ рдХреИрд╕реЗ рдмрджрд▓реЗрдВ? рдорди рдореЗрдВ рдЖрдпрд╛ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдФрд░ рдПрдХ рдХреЗ рд╕рд╛рде рдмрджрд▓рдирд╛ рд╣реИ рдЬреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИред рдлрд┐рд░ рдЖрдк рдЗрд╕реЗ рдкрдХрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
 function add(n,acc) { function add() {throw arguments;} while(true) { try { if(n===0) return acc; return add(n-1,acc+n); } catch($tail$ex) { n = $tail$ex[0]; acc = $tail$ex[1]; } } } 
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЦреБрдж рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЕрдм рдПрдХ рдиреЗрд╕реНрдЯреЗрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХрддрд╛ рд╣реИред рд╣рдо рдЗрдирд╛рдпрдд рд╕реЗ рдЗрд╕реЗ рдкрдХрдбрд╝ рд▓реЗрддреЗ рд╣реИрдВ, рддрд░реНрдХреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдФрд░ рд▓реВрдк рдХреЗ рдЕрдЧрд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд▓реЗрдмрд▓ рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реИ)ред

рд▓реЗрдХрд┐рди рдореИрдВ рд╣рд░ рдмрд╛рд░ рдпрд╣ рд▓рд┐рдЦрдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣реВрдВрдЧрд╛, рдХрд╛рд░реНрдп рдХреЗрд╡рд▓ рд▓рд┐рдЦрдирд╛ рдерд╛ред рдПрдХ рдореЗрдВ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд░реАрдореЗрдХ рдХреИрд╕реЗ рдХрд░реЗрдВ? рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд░рддреЗ рд╣реИрдВ (рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП), рдЗрд╕реЗ рдареАрдХ рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ eval рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ:
 Function.prototype.tail = function() { var funcStr = Object.toString.apply(this); var paramsPos = funcStr.indexOf('('); var paramsEndPos = funcStr.indexOf(')'); var bodyPos = funcStr.indexOf('{'); var bodyEndPos = funcStr.lastIndexOf('}'); var name = funcStr.substring("function".length, paramsPos).replace(/\s*/g, ""); var args = funcStr.substring(paramsPos+1, paramsEndPos).replace(/\s*/g, "").split(","); var body = funcStr.substring(bodyPos+1, bodyEndPos); var paramPassString = ""; for(var i=0; i<args.length; i++) paramPassString += args[i]+"=$tail$ex["+i+"];"; var newBody = "function "+name+"() {throw arguments;} while(true) {try{"+body+ "return;}catch($tail$ex) {"+paramPassString+"}}"; return eval("var $tail$function = function "+name+"("+args.join(",")+") {\n"+ newBody+"};$tail$function"); } 


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ, рдЗрд╕рдХрд╛ рдирд╛рдо, рддрд░реНрдХ рдФрд░ рдирд┐рдХрд╛рдп рдЦреЛрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдлрд┐рд░, рд╢рд░реАрд░ рдХреЗ рд╕рд╛рдордиреЗ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж, рдЕрддрд┐рд░рд┐рдХреНрдд рд▓рд╛рдЗрдиреЗрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╕рдм рдХреБрдЫ рд╡рд╛рдкрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реАрдорд╛рдПрдБ рд╣реИрдВ:

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрдмрдХрд┐ (100000,0) рдХреНрд░реИрд╢, add.tail () (100000,0) рд╕рдм рдХреБрдЫ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЧрд┐рдирддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреА рдХреАрдордд рдХреНрдпрд╛ рд╣реИ? рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдлрдВрдХреНрд╢рди рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдореЗрдВ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рд╕рдордп рдЬреЛрдбрд╝реЗрдВрдЧреЗ:
рдлрд╝рдВрдХреНрд╢рди .prototyp.time = рдлрд╝рдВрдХреНрд╢рди (n) {...}
 Function.prototype.time = function(n) { var start = new Date(); var result; var error; for(var i=0; i<n; i++) { try { result = this(); } catch(ex) { error = ex; } } var time = new Date()-start; var funcStr = Object.toString.apply(this); var bodyPos = funcStr.indexOf('{'); var bodyEndPos = funcStr.lastIndexOf('}'); var body = funcStr.substring(bodyPos+1, bodyEndPos).replace(/^\s*/, "").replace(/\s*$/, ""); if(error) console.log("Code: "+body+"; error: "+error+"; time="+time/n); else console.log("Code: "+body+"; result: "+result+"; time="+time/n); } 

рдлрд╝рдВрдХреНрд╢рди рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╛рд░рдВрдн рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рд╕рдордп рдФрд╕рдд рдХрд░рддрд╛ рд╣реИред рдЗрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЬреЛрдбрд╝реЗрдВ:
 var addTail = add.tail(); (function() {return add(10000,0)}).time(500); (function() {return add(100000,0)}).time(500); (function() {return addTail(10000,0)}).time(500); (function() {return addTail(100000,0)}).time(500); 

рдЕрдм Google Chrome 25 рдореЗрдВ рдпрд╣ рд╕рдм рд╕рд╛рдордЧреНрд░реА рдЪрд▓рд╛рдПрдВ рдФрд░ рдирд┐рд░рд╛рд╢рд╛рдЬрдирдХ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВ:
 Code: return add(10000,0); result: 50005000; time=0.102 Code: return add(100000,0); error: RangeError: Maximum call stack size exceeded; time=0.162 Code: return addTail(10000,0); result: 50005000; time=2.392 Code: return addTail(100000,0); result: 5000050000; time=24.826 

рд╣рд╛рд▓рд╛рдБрдХрд┐ рд╣рдо рдЕрдм рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ 24-рдЧреБрдирд╛ рдХреА рдХрдореА рдХреГрдкрдпрд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдФрд░ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?

рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдзреАрдореА рдЪреАрдЬреЛрдВ (рдЕрдкрд╡рд╛рджреЛрдВ рдФрд░ рддрд░реНрдХреЛрдВ) рдХреЗ рдмрд┐рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЙрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рд╣рдо рдмрджрд▓ рд░рд╣реЗ рд╣реИрдВред рдпрд╣рд╛рдБ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд╛рд░реНрд╕рд░ ( jslint.js рдкрд░ рдЖрдзрд╛рд░рд┐рдд) рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рд╡рд┐рдЪрд╛рд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реЛрдЧреА, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдХреЛрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
 Function.prototype.tail2 = function() { var funcStr = Object.toString.apply(this); var paramsPos = funcStr.indexOf('('); var paramsEndPos = funcStr.indexOf(')'); var bodyPos = funcStr.indexOf('{'); var bodyEndPos = funcStr.lastIndexOf('}'); var name = funcStr.substring("function".length, paramsPos).replace(/\s*/g, ""); var args = funcStr.substring(paramsPos+1, paramsEndPos).replace(/\s*/g, "").split(","); var body = funcStr.substring(bodyPos+1, bodyEndPos); body = body.replace(new RegExp("return\\s+"+name+"\\s*\\((.+?)\\);", "g"), function(match,argsStr) { var passArgs = argsStr.split(","); var result = ""; for(var i=0; i<args.length; i++) result+="var $tail$arg"+i+"="+passArgs[i]+";" for(var i=0; i<args.length; i++) result+=args[i]+"="+"$tail$arg"+i+";" return "{"+result+"continue $tail$label;}"; }); var newBody = "$tail$label:while(true) {"+body+"return;}"; return eval("var $tail$function = function "+name+"("+args.join(",")+") {"+newBody+"};$tail$function"); } 

рдпрд╣рд╛рдВ рд╣рдо рдлреЙрд░реНрдо return < >(val1, val2, ..., valN) рдХреА рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдирд╛ рдХреЛ рдЪрд╛рд▓реВ рдХрд░рддреЗ return < >(val1, val2, ..., valN) рдПрдХ рдмреНрд▓реЙрдХ рдореЗрдВ, рдЬрд╣рд╛рдВ рдордзреНрдпрд╡рд░реНрддреА рдЪрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдо рддрд░реНрдХреЛрдВ рдХреЛ рдирдП рдореВрд▓реНрдп рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдХреЙрд▓ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВред рдореИрдВ рддреБрд░рдВрдд рд╣реА рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдХреЛрдб рдмрд╣реБрдд рднреЛрд▓рд╛ рд╣реИ рдФрд░ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрд╖реНрдардХ рд╣реИрдВ рдпрд╛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рддреЛ?:ред

рд╣рдо рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ:
 var addTail2 = add.tail2(); (function() {return addTail2(10000,0)}).time(500); (function() {return addTail2(100000,0)}).time(500); 
рдкрд░рд┐рдгрд╛рдо рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд╣реИрдВ:
 Code: return addTail2(10000,0); result: 50005000; time=0.022 Code: return addTail2(100000,0); result: 5000050000; time=0.222 

рдпрд╣ рдореВрд▓ рд╕реЗ рднреА рддреЗрдЬ рд╣реИ! рдмреЗрд╢рдХ, рдЕрдм рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдкрд░ рдмрдЪрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рдФрд░ рдХреНрдпрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╣реИ? рдЙрдкрд░реЛрдХреНрдд рд▓реЗрдЦ рд╕реЗ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓ рдХрд╛рд░реНрдп рдХрд░реЗрдВ :
 function cpsFib(n, prev, cur, _return) { if (n < 2) { return _return(cur); } return cpsFib(--n, cur, cur + prev, _return); } function identity(x) {return x} var cpsFibTail = cpsFib.tail(); var cpsFibTail2 = cpsFib.tail2(); (function() {return cpsFib(1300, 0, 1, identity)}).time(5000); (function() {return cpsFibTail(1300, 0, 1, identity)}).time(5000); (function() {return cpsFibTail2(1300, 0, 1, identity)}).time(5000); 

рдкрд░рд┐рдгрд╛рдо:
 Code: return cpsFib(1300, 0, 1, identity); result: 2.159968028316171e+271; time=0.0222 Code: return cpsFibTail(1300, 0, 1, identity); result: 2.159968028316171e+271; time=0.3436 Code: return cpsFibTail2(1300, 0, 1, identity); result: 2.159968028316171e+271; time=0.0036 

рдпрджрд┐ рд╣рдо рд▓реЗрдЦ рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
 Code: return cpsFib.tco(1300, 0, 1, identity); result: 2.159968028316171e+271; time=0.187 

рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рддреЗрдЬрд╝, рд▓реЗрдХрд┐рди рдЕрднреА рднреА рдирд┐рдпрдорд┐рдд рдкреБрдирд░рд╛рд╡рд░реНрддреА рд░реВрдк рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 8 рдЧреБрдирд╛ рдзреАрдорд╛ рдФрд░ рд╣рдорд╛рд░реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 52 рдЧреБрдирд╛ рдзреАрдорд╛ рд╣реИред

рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдРрд╕реА рдЪреАрдЬреЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдордЬрд╝реЗ рдХреЗ рд▓рд┐рдП - рдХреНрдпреЛрдВ рдирд╣реАрдВред рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдорддреМрд░ рдкрд░ рд╡рд╛рдпрд░рд╕ рдФрд░ рдУрдлрд╝реНрдлрд╝реНрдпреВрд╕реЗрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреНрдп рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

Source: https://habr.com/ru/post/In173447/


All Articles