Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does searching for larger strings in a `reversed` string take more time than slice reversing?

As I read here, reversing a string using the reversed function is more efficient than slice notation,string[::-1]. But when I tried it myself, I observed different results.

First, I tried to make a very big string. And then I tried to check how much time it takes to check whether a string exists in the large one or not. This is what I did:

In [1]: large = "abcdefgijklmnopqrstuvwxyz1234567890!@#$%^&*()_=+0}{QWERT"                                                                           

In [2]: large = 1000*large                                                                                                                           

In [3]: large = 1000*large  

In [5]: len(large)                                                                                                                                   
Out[5]: 56000000

In [6]: %time "a" in large[::-1]                                                                                                                     
CPU times: user 63 ms, sys: 43.4 ms, total: 106 ms
Wall time: 106 ms
Out[6]: True

In [7]: %time "a" in reversed(large)                                                                                                                 
CPU times: user 11 µs, sys: 1 µs, total: 12 µs
Wall time: 17.6 µs
Out[7]: True

If I check the existence of only 1 char in large, reversed is much faster, but when I attempt it for bigger strings, the result changes:


In [8]: %time "ab" in large[::-1]                                                                                                                    
CPU times: user 99.2 ms, sys: 44.1 ms, total: 143 ms
Wall time: 143 ms
Out[8]: False

In [9]: %time "ab" in reversed(large)                                                                                                                
CPU times: user 1.73 s, sys: 4.48 ms, total: 1.73 s
Wall time: 1.74 s
Out[9]: False
In [10]: %time "abc" in large[::-1]                                                                                                                  
CPU times: user 125 ms, sys: 20 ms, total: 145 ms
Wall time: 145 ms
Out[10]: False

In [11]: %time "abc" in reversed(large)                                                                                                              
CPU times: user 1.72 s, sys: 6.52 ms, total: 1.73 s
Wall time: 1.74 s
Out[11]: False


What's happening under the hood?

like image 319
Amir reza Riahi Avatar asked Jul 11 '21 11:07

Amir reza Riahi


People also ask

How many ways we can reverse a string in Python?

Python provides two straightforward ways to reverse strings. Since strings are sequences, they're indexable, sliceable, and iterable. These features allow you to use slicing to directly generate a copy of a given string in reverse order.

What does it mean to reverse a string?

In programming, a string is a sequence of characters. It is one of the basic data types that we use to express text rather than numbers. Reversing a string means flipping the order of the characters completely. In other words, we are making the string read backwards.


1 Answers

The two are not the same, and may produce different boolean outcomes. For instance:

s = "ab"
print("ba" in s[::-1])  # True
print("ba" in reversed(s))  # False

The in operator on a string has different behaviour: it looks for a substring match. The in operator on a iterator will try to find a match on individually iterated values, i.e. single characters in this case.

So you cannot really compare these like that.

As to why it is slower to get a False outcome: the iterator will create separate strings for each iterated character to which then the needle string ("ba") is compared from scratch.

In the string version, there is an optimised search algorithm to find a substring in a larger string, which is one operation for Python. The efficient string search algorithm is implemented in lower level code, like C.

like image 78
trincot Avatar answered Oct 11 '22 18:10

trincot