python - Boosting time for multiple for loops in list comprehensions -


i looking method lower execution time python 3.5 takes 2 for-loops in list comprehension looks this:

[[(k1-k2)**power k2 in range(m,n)] k1 in range(m,n)] 

so, started off current approach , found while work, quite slow. first attempt involved transforming list comprehension suitable approach numpy arrays. 3 times faster original approach, that's when noticed quite beautiful: symmetric toeplitz matrix. wiki page:

in linear algebra, toeplitz matrix or diagonal-constant matrix, named after otto toeplitz, matrix in each descending diagonal left right constant.

i first used default scipy implementation of toeplitz matrix, approach unnecessary slow problem. wrote myself similar approach, third attempt below.

methodology

i ran 10 tests each approach, each individual test comprising 1000 runs. set parameters m = 10, n = 100. results can found in table below:

    approach       numpy #1     numpy #2     numpy #3 1        4.573965       1.432406     1.060242     0.186767 2        4.341466       1.432237     1.060404     0.186872 3        4.442438       1.434460     1.144850     0.183120 4        4.318919       1.456928     1.072072     0.185626 5        4.249392       1.450684     1.072217     0.183273 6        4.202730       1.508863     1.070299     0.183019 7        4.224226       1.457543     1.065354     0.183591 8        4.234505       1.432971     1.082438     0.185711 9        4.256538       1.431828     1.080051     0.184290 10       4.241055       1.557204     1.083070     0.185845  avg      4.308523       1.459512     1.079100     0.184811 std      0.117433       0.041693     0.024538     0.001521 

the scipy toeplitz approach (numpy #2 in table) 4 times faster current approach, these results dwarfed third , final approach: whopping 23 times speed on initial implementation!

now, since interested in time complexity, let n vary, keeping m = 10. results each approach can found in figure below:

time complexity of different approaches.

clearly, third approach way go!

code

full code:

import timeit import numpy np scipy.linalg import toeplitz   def your_approach(m, n):     print("\n\tlist comprehension")     k = range(m, n)     in range(1, 11):         start = timeit.default_timer()         j in range(1, 1001):             data_list_comp = [[(k1 - k2) ** 2 k2 in k] k1 in k]         print("\t{}".format(timeit.default_timer() - start))     return data_list_comp   def numpy1(m, n):     print("\n\tnumpy")     k_n = np.array(range(m, n))     in range(1, 11):         start = timeit.default_timer()         j in range(1, 1001):             data_numpy = [list((k_n - x) ** 2) x in k_n]         print("\t{}".format(timeit.default_timer() - start))     return data_numpy   def numpy2(m, n):     print("\n\ttoeplitz")     k_n = np.array(range(0, n - m)) ** 2     toep = toeplitz(k_n)     in range(1, 11):         start = timeit.default_timer()         j in range(1, 1001):             data_numpy = [list(toep[:, i]) in range(n - m)]         print("\t{}".format(timeit.default_timer() - start))     return data_numpy  def numpy3(m, n):     print("\n\ttoeplitz2")     k_n = list(np.array(range(0, n - m)) ** 2)  # can done without numpy, bit lazy. :)     in range(1, 11):         start = timeit.default_timer()         j in range(1, 1001):             data_numpy = [(k_n[i::-1] + k_n[1:-i]) if != 0 else k_n in range(0, n - m)]         print("\t{}".format(timeit.default_timer() - start))     return data_numpy  m = 10  n in [25, 50, 100, 150, 200]:     assert your_approach(m, n) == numpy1(m, n) == numpy2(m, n) == numpy3(m, n) 

Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

c - Unrecognised emulation mode: elf_i386 on MinGW32 -