Using your version of F #, I got:
> e28(100000L);; Real: 00:00:00.061, CPU: 00:00:00.062, GC gen0: 2, gen1: 0, gen2: 0 val it : int64 = 666691667100001L
Using:
let e28d N = seq {2L..2L..N} |> Seq.collect(fun x->seq{yield x;yield x; yield x; yield x}) |> Seq.scan (+) 1L |> Seq.sum
I got:
> e28d(100000L);; Real: 00:00:00.040, CPU: 00:00:00.031, GC gen0: 2, gen1: 0, gen2: 0 val it : int64 = 666691667100001L
You will probably have a hard time getting Python to work with both F # and since F # has been compiled and interpreted by Python. At the same time, the above improvement will work on python too:
>>> def e28a(N = 100000): diagNumber = 1; sum = diagNumber; for width in range(2, N+1, 2): for j in range(4): diagNumber += width; sum += diagNumber; return sum; >>> if __name__ == '__main__': import timeit print(timeit.timeit("e28a()", setup="from __main__ import e28a", number=10)) 0.5249497228663813 >>> def e28a(N = 100000): diagNumber = 1; sum = diagNumber; for width in range(2, N+1, 2): diagNumber += width; sum += diagNumber; diagNumber += width; sum += diagNumber; diagNumber += width; sum += diagNumber; diagNumber += width; sum += diagNumber; return sum; >>> if __name__ == '__main__': import timeit print(timeit.timeit("e28a()", setup="from __main__ import e28a", number=10)) 0.2585966329330063 >>>
Part of this improvement comes from fewer function calls, that is:
>>> def e28a(N = 100000): diagNumber = 1; sum = diagNumber; temp_range = range(4)
And I think the other part comes from deleting the loop. Both of them can be quite expensive in Python.
source share