F #: рд╕рдВрдХрд▓рди рдХреЗ рдмрд╛рдж рдЖрдкрдХрд╛ рдХреЛрдб рдХреНрдпрд╛ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ

рдПрдл # рднрд╛рд╖рд╛ рдорд╛рдирдХ VisualStudio рдкреИрдХреЗрдЬ рдореЗрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдЕрд░реНрдерд╛рддреН 2010 рд╕рдВрд╕реНрдХрд░рдг (рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ)ред рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рд╣рд░ рдХреЛрдИ рдпрд╣ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЬрд╛рдирддрд╛ рд╣реИ, рднрд╛рд╖рд╛ CLR рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд╛рд░реНрдп рдХрд░рддреА рд╣реИ - рдЖрдкрдХреЗ рд╕рднреА рдХреЛрдб рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп .NET рднрд╛рд╖рд╛ рдХреА рддрд░рд╣ MS IL рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдЖрдкрдХреЗ рдХреЛрдб рдХреЛ рдХрд┐рд╕ рддрд░рд╣ рд╕реЗ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдФрд░ рдЙрдкрдпреЛрдЧреА рдпрд╛рдж рд░рдЦрдиреЗ рдХреА рддрдХрдиреАрдХ рдХреЗ рд░реВрдк рдореЗрдВред рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ F # рдореЗрдВ рдХреЛрдб рд▓рд┐рдЦреВрдВрдЧрд╛ рдФрд░ рдЗрд╕реЗ C # рдореЗрдВ рдЕрдкрдШрдЯрд┐рдд рдХрд░реВрдВрдЧрд╛ред

рддреЛ, рдореВрд▓ рдЙрджрд╛рд╣рд░рдг:
let memoize f = let cache = System.Collections.Generic.Dictionary() fun x -> if cache.ContainsKey(x) then cache.[x] else let res = fx cache.[x] <- res res let rec memoizedFactorial = let factorial x = match x with | a when a = 0I -> 1I | x -> x * memoizedFactorial (x - 1I) memoize factorial let now = System.DateTime.Now let arguments = [10000I .. 10100I] let factorials = arguments |> List.map memoizedFactorial let timeDiff = System.DateTime.Now - now printfn "Time: %A" timeDiff 


рдХреБрдЫ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг:


рдЖрдЗрдП рдЕрдм рджреЗрдЦреЗрдВ рдХрд┐ рд╕реНрдорд╛рд░рдХ рдХрд┐рд╕рдХреЗ рдиреЗрддреГрддреНрд╡ рдореЗрдВ рдЪрд▓рд╛ред
рд╕рдВрд╕реНрдорд░рдг рдХреЗ рдмрд┐рдирд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп 28.97 рд╕реЗрдХреЗрдВрдб рд╣реИ, рдФрд░ рд╕рдВрд╕реНрдорд░рдг 0.89 s рдХреЗ рд╕рд╛рдеред рдЬреИрд╕рд╛ рдХрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкреНрд░рднрд╛рд╡ рд╕реНрдкрд╖реНрдЯ рд╣реИред

рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕рдм рдХреНрдпрд╛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред C # рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдмрд┐рдВрджреБ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ memoizedFactorial рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ memoizedFactorial рд╣реИред рд╕реНрдерд╛рдиреАрдп рдлрд╝рдВрдХреНрд╢рди рдХреИрд╢ рдХреЛ рдлрд┐рд░ рд╕реЗ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ?
рдЪрд▓реЛ рджреЗрдЦрддреЗ рд╣реИрдВред

main рд╕рдорд╛рд░реЛрд╣:
 public static void main@() { memoizedFactorial@11-1 = LazyExtensions.Create<FSharpFunc<BigInteger, BigInteger>>(new Program.clo@11-1()); memoizedFactorial@11 = Program.memoizedFactorial@11.get_Value(); now@18 = DateTime.Now; arguments@20 = SeqModule.ToList<BigInteger>(new Program.arguments@20(0, new BigInteger())); factorials@21 = ListModule.Map<BigInteger, BigInteger>(Program.memoizedFactorial, Program.arguments); timeDiff@23 = (TimeSpan) (DateTime.Now - Program.now); fp@1 = new PrintfFormat<FSharpFunc<TimeSpan, Unit>, TextWriter, Unit, Unit, TimeSpan>("Time: %A"); PrintfModule.PrintFormatLineToTextWriter<FSharpFunc<TimeSpan, Unit>>(Console.Out, Program.fp@1).Invoke(Program.timeDiff); } 


рд╣рдореНрдо ... memoizedFactorial рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЕрд▓рдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрди рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд╣рд╛рдБ рдХреЛрдИ рдЪрд░ рдирд╣реАрдВ рд╣реИрдВ - рд╡реЗ рд╕рднреА рд╡рд░реНрдЧ internal static class $Program рдХреНрд╖реЗрддреНрд░ рдмрди рдЧрдПред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрдХреНрд╖рд╛рдУрдВ рддрдХ, рдХреЛрдб рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред memoizedFactorial рдореЗрдВ memoizedFactorial рд╕реЗ memoizedFactorial ред

рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ $Program рд╡рд░реНрдЧ рдХреЗ рджреЛ рдХреНрд╖реЗрддреНрд░ рд╣реИрдВ:
 internal static FSharpFunc<BigInteger, BigInteger> memoizedFactorial@11; internal static Lazy<FSharpFunc<BigInteger, BigInteger>> memoizedFactorial@11-1; 


рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рджреВрд╕рд░рд╛ рдорд╛рдирдХ рд╡рд░реНрдЧ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рджреНрд╡рд╛рд░рд╛ рдЖрд░рдореНрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреНрд▓реЛрдЬрд░ рдкрд╛рд╕ рд╣реЛрддрд╛ рд╣реИред рдкрд╣рд▓рд╛ рдХреНрд╖реЗрддреНрд░ рдХреБрдЫ рднреА рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл рдЦреБрдж рдХреЛ рд╡рд╛рдкрд╕ рд▓рд╛рддрд╛ рд╣реИ ( get_Value рд╡рд┐рдзрд┐)ред

рддреЛ, рдмрдВрдж рд▓рдЧ рд░рд╣рд╛ рд╣реИ:
 internal class clo@11-1 : FSharpFunc<Unit, FSharpFunc<BigInteger, BigInteger>> { // Methods internal clo@11-1(); public override FSharpFunc<BigInteger, BigInteger> Invoke(Unit arg00@); } 


рд╣рдо рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рд╡рд┐рдзрд┐ рд╣реИ:
 public override FSharpFunc<BigInteger, BigInteger> Invoke(Unit arg00@) { return Program.memoizedFactorial@11-1(); } 


рд╣рдореНрдоред рдРрд╕рд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ рдХрд┐ рд╡реЗ рд╡рд╣рд╛рдВ рдЖрдП рдЬрд╣рд╛рдВ рд╡реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдереЗред рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд╣реИ рдирд╣реАрдВред рдпрд╣ memoizedFactorial@11-1 рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред рдЕрдВрдд рдореЗрдВ, рд╣рдо рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:
 internal static FSharpFunc<BigInteger, BigInteger> memoizedFactorial@11-1() { return memoize<BigInteger, BigInteger>(new clo@13()); } 


рдпрд╣рд╛рдБ! рдЕрдВрдд рдореЗрдВ рд╣рдореЗрдВ memoize рдлрдВрдХреНрд╢рди рдорд┐рд▓рд╛ред рдФрд░ рдПрдХ рдФрд░ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдПрдХ рдХреНрд▓реЛрдЬрд░ рдЙрд╕реА рд╡рд░реНрдЧ рдХрд╛ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рд╣реИ, рд╣рдо рддреБрд░рдВрдд рдЗрдирд╡реЛрдХ рд╡рд┐рдзрд┐ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:
 public override BigInteger Invoke(BigInteger x) { if (LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<BigInteger>(x, BigInteger.Zero)) { return BigInteger.One; } return (x * Program.memoizedFactorial@11.get_Value().Invoke(x - BigInteger.One)); } 


рдпрд╣рд╛рдБ рдпрд╣ рд╣рдорд╛рд░реА рд╕рдЪреНрдЪрд╛рдИ рд╣реИ! рд╣рдордиреЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкрд╛рдпрд╛ рдЬреЛ рд╕реАрдзреЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдПрдХ рд╕реНрдорд╛рд░рдХ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдПрдл # рдХреЛрдб рдореЗрдВ рд▓рд┐рдЦрд╛ рдерд╛ред рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХреЛ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ if ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рджреЛ BigInteger рддреБрд▓рдирд╛ рдЙрдирдХреЗ рд╣реИрд╢ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИред

рдЪрд▓реЛ рдПрдХ рдХрджрдо рдкреАрдЫреЗ рдЪрд▓рддреЗ рд╣реИрдВ рдФрд░ memoize рд╕рдорд╛рд░реЛрд╣ рдХреЛ memoize рд╣реИрдВ:
 public static FSharpFunc<a, b> memoize<a, b>(FSharpFunc<a, b> f) { return new memoize@3<a, b>(f, new Dictionary<a, b>()); } 


рдЗрдзрд░, рдорд╕реНрддреА рд╢реБрд░реВ рд╣реБрдИред рдХрд╛рд░реНрдп рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЙрди рдирд┐рд░реНрдорд╛рддрд╛ рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рдирдореЗрдВ рд╕реЗ рд╣рдорд╛рд░рд╛ рдХреНрд▓реЛрдЬрд░ (рдкрд╣рд▓рд╛ рддрд░реНрдХ) рдФрд░ рд╢рдмреНрджрдХреЛрд╢ (рджреВрд╕рд░рд╛ рддрд░реНрдХ) рдкрд╛рд╕ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдм рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╣рд░ рдмрд╛рд░ рд╢рдмреНрджрдХреЛрд╢ рдХреЛ рдлрд┐рд░ рд╕реЗ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

рд╣рдо рдЧрд╣рд░рд╛рдИ рддрдХ рдЬрд╛рддреЗ рд╣реИрдВ:
 internal class memoize@3<a, b> : FSharpFunc<a, b> { // Fields public Dictionary<a, b> cache; public FSharpFunc<a, b> f; // Methods internal memoize@3(FSharpFunc<a, b> f, Dictionary<a, b> cache); public override b Invoke(ax); } 


рд╡рд░реНрдЧ рдлрд╝реАрд▓реНрдб рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╢ рдкреВрд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрдпреЛрдВ рд╣реИред рд╣рдо Invoke рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:
 public override b Invoke(ax) { if (this.cache.ContainsKey(x)) { return this.cache[x]; } b res = this.f.Invoke(x); this.cache[x] = res; return res; } 


рдФрд░ рдпрд╣рд╛рдБ рд╣рдорд╛рд░реЗ рд╕реНрдорд╛рд░рдХ рд╕рдорд╛рд░реЛрд╣ рд╣реИ! рдХреБрдВрдЬреА рдХреЛ рддрд░реНрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреНрд▓реЛрдЬрд░ f рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╡рд╕реНрддреБ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдирддреЗ рд╣реИрдВред рд░рд╣рд╕реНрдп рдЕрдирд╕реБрд▓рдЭрд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП F # рдореЗрдВ рдХреЛрдИ рдЬрд╛рджреВ рдирд╣реАрдВ рд╣реИред рдЦреИрд░, рдмрд┐рд▓реНрдХреБрд▓ред рдЗрди рд╕рднреА рдХрд░реА (рдФрд░ memoizedFactorial рдлрд╝рдВрдХреНрд╢рди memoizedFactorial рдХреНрдпрд╛ рд╣реИ), рдкреНрд░рдердо рд╢реНрд░реЗрдгреА рдХреЗ рдирд╛рдЧрд░рд┐рдХреЛрдВ рдЬреИрд╕реЗ рдХрд╛рд░реНрдп рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдХрдХреНрд╖рд╛рдПрдВ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИрдВред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдореЗрд░рд╛ рд▓реЗрдЦ рдХрд┐рд╕реА рдХреЛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ рдХрд┐ рдПрдл # рдЕрдВрджрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

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


All Articles