I have 2 codes which do similar task:
class Solution1:
def f(self, s: str) -> bool:
def calculate(s, i, digit, length, maxi):
count = 1
while i < length:
if s[i] == digit: count += 1
else: break
i += 1
return max(maxi, count), i
maxi1 = 0
maxi0 = 0
length = len(s)
i = 0
while i<length:
if s[i] == '0': maxi0, i = calculate(s,i,'0', length, maxi0)
else: maxi1, i = calculate(s,i,'1', length, maxi1)
return maxi1 > maxi0
class Solution3:
def f(self, s: str) -> bool:
s1 = s.split('0')
s0 = s.split('1')
r1 = max([len(i) for i in s1])
r0 = max([len(i) for i in s0])
return r1>r0
Running the following codes with %timeit,
x = '1100011111100111010111'*10
sol1 = Solution1().f
sol3 = Solution3().f
% timeit -r 30 -n 3000 sol1(x,)
% timeit -r 30 -n 3000 sol3(x,)
it gives me,
3000 loops, best of 30: 77.5 µs per loop
3000 loops, best of 30: 29.6 µs per loop
it is weird that the second code takes almost half time.
split() iterates over the loop once and has been used twice, then len takes the O(N) time for each subpart and has been called for every sub string meaning a total of O(N) time and on top of that and max works exactly the same for both. Can someone explain how this might be happening? Is it the cpython doing something under the hood for inbuilt functions?
and to my surprise:
class Solution4:
def f(self, s: str) -> bool:
return len(max(s.split('0'))) > len(max(s.split('1')))
takes 7x less time given max is used on strings + split() twice.