from micropython import const
from vts import Chrono, delay_ms as sleep
from math import log10, isnan, floor, isfinite


t = Chrono()
ITERATIONS = const(10000)
value = -123456.78910

def string_split(val):
    return len(str(val).split('.')[0])

def string_index(val):
    return str(val).index('.')

def log10_count(val):
    if isinstance(val, (int,float)) and isfinite(val) and (val > 1):
        return floor(log10(abs(val))) + 1
    else:
        return 1

def loop_count(val):
    count = 0
    if (val) and (not isnan(val)):
        val = int(val)
        while val >= 1:
            val //= 10
            count += 1
        return count
    else:
        return 1

# @micropython.viper
# def loop_count(val):
#     count = int(0)
#     if (val) and (not isnan(val)):
#         val = int(val)
#         while val >= 1:
#             val //= 10
#             count += 1
#         return count
#     else:
#         return 1




# @micropython.native
# def native_pack(l):
#     m_list.extend(l)

# # @micropython.viper
# # def viper_write_8_Bit(l, pos: int):
# #     global store
# #     for i in l:
# #         ptr8(store)[pos] = int(i)
# #         pos += 1

# @micropython.viper
# def viper_write(l):
#     m_list.extend(l)

@micropython.asm_thumb
def leading_zeros(r0):
    clz(r0, r0) # return no. of leading zeros in passed 32 bit integer

if __name__ == "__main__":

    a = 0

    # t.restart()
    # for i in range(ITERATIONS): a = string_split(value)
    # print('Function \'{}\' gave a value of {} \tTime = {:6.3f}ms'.format('String split', a, t.read()/1000))

    # t.restart()
    # for i in range(ITERATIONS): a = string_index(value)
    # print('Function \'{}\' gave a value of {} \tTime = {:6.3f}ms'.format('String Index', a, t.read()/1000))

    t.restart()
    for i in range(ITERATIONS): a = log10_count(value)
    print('Function \'{}\' gave a value of {} \tTime = {:6.3f}ms'.format('Log_10_count', a, t.read()/1000))

    t.restart()
    for i in range(ITERATIONS): a = loop_count(value)
    print('Function \'{}\' gave a value of {} \tTime = {:6.3f}ms'.format('Loop_Count', a, t.read()/1000))

    t.restart()
    for i in range(ITERATIONS): a = loop_count(value)
    print('Function \'{}\' gave a value of {} \tTime = {:6.3f}ms'.format('ASM', a, t.read()/10000))

#     reset()
#     t.restart()
#     for i in range(ITERATIONS): ustruct_pack_tuple(payload)
#     print('Function \'{}\' Time = {:6.3f}ms'.format('ustruct_pack', t.read()/1000))
#     print(store[int((len(store)/2) + 1)])

#     reset()
#     t.restart()
#     for i in range(ITERATIONS): array_extend(payload)
#     print('Function \'{}\' Time = {:6.3f}ms'.format('array_extend', t.read()/1000))
#     print(ar_1[int((len(ar_1)/2) + 1)])

#     reset()
#     t.restart()
#     for i in range(ITERATIONS): basic_list(payload)
#     print('Function \'{}\' Time = {:6.3f}ms'.format('basic_List', t.read()/1000))
#     print(m_list[int((len(m_list)/2) + 1)])

#     reset()
#     t.restart()
#     for i in range(ITERATIONS): native_pack(payload)
#     print('Function \'{}\' Time = {:6.3f}ms'.format('Native_Pack', t.read()/1000))
#     print(m_list[int((len(m_list)/2) + 1)])
#     # print(store[int((len(store)/2) + 1)])

#     reset()
#     t.restart()
#     for i in range(ITERATIONS): viper_write(payload)
#     print('Function \'{}\' Time = {:6.3f}ms'.format('viper_write', t.read()/1000))
#     # print(m_list[int((len(m_list)/2) + 1)])
#     print(m_list[int((len(m_list)/2) + 1)])
#     print(" ------------------------- \n")

# ''' Conclusions:
#     >50 Iterations:
#         # Extending list is quicker than converting to bytearray or array
#         # Native Emitter and Viper Emitter provide minimal benifit in this instance
#         # Pre-allocating list or byte-array is slower than extending

#     >100 Iterations:
#         # Extending list is quicker than converting to bytearray or array
#         # Native Emitter and Viper Emitter provide minimal benifit in this instance
#         # Pre-allocating list or byte-array is slower than extending

#     >500 Iterations:
#         # Extending list is quicker than converting to bytearray
#         # array offers significant benifit over bytearray and similar performance to list
#         # Native Emitter does not speed anything up in this case
#         # Viper Emitter provides a small benifit
#         # Pre-allocating list or byte-array is slower than extending

#     >1000 Iterations:
#         # array-extend now the fastest method
#         # converting to bytearray or array quicker than list
#         # Native Emitter does not speed anything up in this case
#         # Viper Emitter provides small benifit
#         # Pre-allocating list or byte-array is slower than extending

#     >5000 Iterations:
#         # array-extend still the fastest method
#         # converting to bytearray or array quicker than list
#         # ustruct.pack_into now offers similar performance to array
#         # Native Emitter does not speed anything up in this case (quicker than viper though)
#         # Viper Emitter does not speed anything up
#         # Pre-allocating list or byte-array is faster than extending

# '''
