@reagentx/

Find Crossover

Python

No description

fork
loading
Files
  • main.py
  • viz.png

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.3142573873299461","path":"main.py","file":{"path":"main.py","content":{"asEncoding":{"base64":"aW1wb3J0IHRpbWVpdAppbXBvcnQgdGltZQoKaW1wb3J0IHBhbmRhcyBhcyBwZAoKCmJhc2UgPSAyCnBvd2VyID0gMgppdGVyYXRpb25zID0gMTAwMDAwCgoKZGVmIGdlbmVyYXRlX211bHRfZnVuYyhuKToKICAgIG11bHRfc3RlcHMgPSAnKicuam9pbihbJ3EnXSAqIG4pCiAgICBmdW5jX3N0cmluZyA9IGYnbGFtYmRhIHE6IHttdWx0X3N0ZXBzfScgICMgS2VlcCB0aGlzIHNvIHdlIGNhbiBwcmludCBsYXRlcgogICAgcmV0dXJuIGV2YWwoZnVuY19zdHJpbmcpLCBmdW5jX3N0cmluZwoKCmV4cG9uZW50ID0gbGFtYmRhIGJhc2UsIHBvd2VyOiBiYXNlICoqIHBvd2VyCm11bHRpcGx5LCBmdW5jX3N0cmluZyA9IGdlbmVyYXRlX211bHRfZnVuYyhwb3dlcikKCgojIEZpbmQgaW5pdGlhbCBzcGVlZHMKbXVsdGlwbHlfc3BlZWQgPSB0aW1laXQudGltZWl0KCdtdWx0aXBseShiYXNlKScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXA9ImZyb20gX19tYWluX18gaW1wb3J0IGJhc2UsIG11bHRpcGx5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXI9aXRlcmF0aW9ucykKZXhwb25lbnRfc3BlZWQgPSB0aW1laXQudGltZWl0KCdleHBvbmVudChiYXNlLCBwb3dlciknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwPSJmcm9tIF9fbWFpbl9fIGltcG9ydCBiYXNlLCBwb3dlciwgZXhwb25lbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlcj1pdGVyYXRpb25zKQptYXRoX3Bvd19zcGVlZCA9IHRpbWVpdC50aW1laXQoJ21hdGgucG93KGJhc2UsIHBvd2VyKScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXA9ImZyb20gX19tYWluX18gaW1wb3J0IGJhc2UsIHBvd2VyOyBpbXBvcnQgbWF0aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyPWl0ZXJhdGlvbnMpCgpwcmludCgnU3RhcnRpbmcgc3BlZWRzOicpCnByaW50KGYnTXVsdGlwbHk6IHttdWx0aXBseV9zcGVlZCoxMDAwOjAuMmZ9IG1zJykKcHJpbnQoZidFeHBvbmVudDoge2V4cG9uZW50X3NwZWVkKjEwMDA6MC4yZn0gbXMnKQpwcmludChmJ21hdGgucG93OiB7bWF0aF9wb3dfc3BlZWQqMTAwMDowLjJmfSBtcycpCgoKIyBTYXZlIHRoZSBkYXRhIHdlIGNhbiBhbmFseXplIGxhdGVyCmRhdGEgPSB7CiAgICAnbXVsdGlwbHknOiBbbXVsdGlwbHlfc3BlZWRdLAogICAgJ2V4cG9uZW50JzogW2V4cG9uZW50X3NwZWVkXSwKICAgICdtYXRoLnBvdyc6IFttYXRoX3Bvd19zcGVlZF0sCiAgICAnUG93ZXInOiBbcG93ZXJdCn0KCgp0MCA9IHRpbWUudGltZSgpCndoaWxlIGV4cG9uZW50X3NwZWVkID49IG11bHRpcGx5X3NwZWVkOgojIGZvciBpIGluIHJhbmdlKDEwMDApOgogICAgIyBwcmludChpKQogICAgcG93ZXIgKz0gMQogICAgIyBHZXQgdGhlIG5leHQgbXVsdGlwbHkgZnVuYwogICAgbXVsdGlwbHksIGZ1bmNfc3RyaW5nID0gZ2VuZXJhdGVfbXVsdF9mdW5jKHBvd2VyKQogICAgYXNzZXJ0KG11bHRpcGx5KGJhc2UpID09IGV4cG9uZW50KGJhc2UsIHBvd2VyKSkKCiAgICAjIEZpbmQgbmV3IHNwZWVkcwogICAgbXVsdGlwbHlfc3BlZWQgPSB0aW1laXQudGltZWl0KCdtdWx0aXBseShiYXNlKScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cD0iZnJvbSBfX21haW5fXyBpbXBvcnQgYmFzZSwgbXVsdGlwbHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyPWl0ZXJhdGlvbnMpCiAgICBleHBvbmVudF9zcGVlZCA9IHRpbWVpdC50aW1laXQoJ2V4cG9uZW50KGJhc2UsIHBvd2VyKScsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXA9ImZyb20gX19tYWluX18gaW1wb3J0IGJhc2UsIHBvd2VyLCBleHBvbmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXI9aXRlcmF0aW9ucykKICAgIG1hdGhfcG93X3NwZWVkID0gdGltZWl0LnRpbWVpdCgnbWF0aC5wb3coYmFzZSwgcG93ZXIpJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwPSJmcm9tIF9fbWFpbl9fIGltcG9ydCBiYXNlLCBwb3dlcjsgaW1wb3J0IG1hdGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyPWl0ZXJhdGlvbnMpCiAgICAKICAgICMgQWRkIHRvIG91ciBkaWN0IG9mIGRhdGEKICAgIGRhdGFbJ211bHRpcGx5J10uYXBwZW5kKG11bHRpcGx5X3NwZWVkKQogICAgZGF0YVsnZXhwb25lbnQnXS5hcHBlbmQoZXhwb25lbnRfc3BlZWQpCiAgICBkYXRhWydtYXRoLnBvdyddLmFwcGVuZChtYXRoX3Bvd19zcGVlZCkKICAgIGRhdGFbJ1Bvd2VyJ10uYXBwZW5kKHBvd2VyKQoKcHJpbnQoZidcbkNyb3Nzb3ZlciBmb3VuZCBpbiB7dGltZS50aW1lKCkgLSB0MDowLjJ9IHM6JykKcHJpbnQoZidCYXNlLCBwb3dlciBcdHtiYXNlfSwge3Bvd2VyfScpCnByaW50KGYnTXVsdGlwbHkgdGltZVx0e211bHRpcGx5X3NwZWVkKjEwMDA6MC4yZn0gbXMnKQpwcmludChmJ0V4cG9uZW50IHRpbWVcdHtleHBvbmVudF9zcGVlZCoxMDAwOjAuMmZ9IG1zJykKcHJpbnQoZidtYXRoLnBvdyB0aW1lXHR7bWF0aF9wb3dfc3BlZWQqMTAwMDowLjJmfSBtcycpCnByaW50KGYnTXVsdGlwbHkgZnVuY1x0e2Z1bmNfc3RyaW5nfScpCgojIEhhbmRsZSB2aXoKZGYgPSBwZC5EYXRhRnJhbWUuZnJvbV9kaWN0KGRhdGEpCmRmLnNldF9pbmRleCgnUG93ZXInLCBkcm9wPVRydWUsIGlucGxhY2U9VHJ1ZSkKZGYudG9fY3N2KCdkYXRhLmNzdicsIGZsb2F0X2Zvcm1hdD0nJS40MGYnKQpwbG90ID0gZGYucGxvdCh0aXRsZT1mJ0V4ZWN1dHV0aW9uIHRpbWUgKHMpIGZvciB7aXRlcmF0aW9uczosfSBpdGVyYXRpb25zJykuZ2V0X2ZpZ3VyZSgpCnBsb3Quc2F2ZWZpZygndml6LnBuZycpCg=="},"asBuffer":null},"loaded":true}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import timeit
import time

import pandas as pd


base = 2
power = 2
iterations = 100000


def generate_mult_func(n):
    mult_steps = '*'.join(['q'] * n)
    func_string = f'lambda q: {mult_steps}'  # Keep this so we can print later
    return eval(func_string), func_string


exponent = lambda base, power: base ** power
multiply, func_string = generate_mult_func(power)


# Find initial speeds
multiply_speed = timeit.timeit('multiply(base)',
                                setup="from __main__ import base, multiply",
                                number=iterations)
exponent_speed = timeit.timeit('exponent(base, power)',
                                setup="from __main__ import base, power, exponent",
                                number=iterations)
math_pow_speed = timeit.timeit('math.pow(base, power)',
                                setup="from __main__ import base, power; import math",
                                number=iterations)

print('Starting speeds:')
print(f'Multiply: {multiply_speed*1000:0.2f} ms')
print(f'Exponent: {exponent_speed*1000:0.2f} ms')
print(f'math.pow: {math_pow_speed*1000:0.2f} ms')


# Save the data we can analyze later
data = {
    'multiply': [multiply_speed],
    'exponent': [exponent_speed],
    'math.pow': [math_pow_speed],
    'Power': [power]
}


t0 = time.time()
while exponent_speed >= multiply_speed:
# for i in range(1000):
    # print(i)
    power += 1
    # Get the next multiply func
    multiply, func_string = generate_mult_func(power)
    assert(multiply(base) == exponent(base, power))

    # Find new speeds
    multiply_speed = timeit.timeit('multiply(base)',
                            setup="from __main__ import base, multiply",
                            number=iterations)
    exponent_speed = timeit.timeit('exponent(base, power)', 
                            setup="from __main__ import base, power, exponent",
                            number=iterations)
    math_pow_speed = timeit.timeit('math.pow(base, power)',
                            setup="from __main__ import base, power; import math",
                            number=iterations)
    
    # Add to our dict of data
    data['multiply'].append(multiply_speed)
    data['exponent'].append(exponent_speed)
    data['math.pow'].append(math_pow_speed)
    data['Power'].append(power)

print(f'\nCrossover found in {time.time() - t0:0.2} s:')
print(f'Base, power \t{base}, {power}')
print(f'Multiply time\t{multiply_speed*1000:0.2f} ms')
print(f'Exponent time\t{exponent_speed*1000:0.2f} ms')
print(f'math.pow time\t{math_pow_speed*1000:0.2f} ms')
print(f'Multiply func\t{func_string}')

# Handle viz
df = pd.DataFrame.from_dict(data)
df.set_index('Power', drop=True, inplace=True)
df.to_csv('data.csv', float_format='%.40f')
plot = df.plot(title=f'Executution time (s) for {iterations:,} iterations').get_figure()
plot.savefig('viz.png')