Python'da bir kitapta bulduğum iki örneği (orijinal olarak Java'da yazılmış) çoğaltmaya çalışıyorum.Bit vektörü vs boole değerleri performansının listesi
İki işlev, bir dizenin tekrarlanan karakterler içerip içermediğini kontrol eder. İlk işlev, bir bit vektörü olarak bir tamsayı (checker
) kullanır, ikinci işlev ise sadece booleanların bir listesini kullanır. İşlevi bits kullanarak daha iyi bir performansa sahip olmayı beklerdim, ancak aslında daha da kötü performans gösteriyor.
Neden? Java'dan Python'a "çeviri" yaparken yanlış bir şey mi yazdım?
Not: basitlik için yalnızca küçük harfler (bir ziçin), özellikle bit vektör işlevini kullanın.
import sys
import timeit
def is_unique_chars_bit(my_str):
checker = 0
for char in my_str:
val = ord(char) - ord('a')
if ((checker & (1 << val)) > 0):
return False
checker |= (1 << val)
return True
def is_unique_chars_list(my_str):
if len(my_str) > 128:
# Supposing we use ASCII, which only has 128 chars
return False
char_list = [False] * 128
for char in my_str:
val = ord(char)
if char_list[val]:
return False
char_list[val] = True
return True
if __name__ == '__main__':
alphabet = "abcdefghijklmnopqrstuvwxyz"
t_bit = timeit.Timer("is_unique_chars_bit('"+ alphabet +"')", "from __main__ import is_unique_chars_bit")
t_list = timeit.Timer("is_unique_chars_list('"+ alphabet +"')", "from __main__ import is_unique_chars_list")
print(t_bit.repeat(3, 200000))
print(t_list.repeat(3, 200000))
Sonuçlar:
[1.732477278999795, 1.7263494359995093, 1.7404333820004467]
[0.6785205180003686, 0.6759967380003218, 0.675434408000001]
orijinal Java işlevleri şunlardır:
tamsayılar Python değişmez referans sınıfları vardır çünküboolean isUniqueCharsBoolArray(String str) {
if (str.length() > 128) return false;
boolean[] char_set = new boolean[128];
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i);
if (char_set[val]) {
return false;
}
char_set[val] = true;
}
return true;
}
boolean isUniqueCharsBits(String str) {
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) -'a';
if ((checker & (1 << val)) > 0) {
return false;
}
checker |= (1 << val);
}
return true;
}
ek bir yöntem sağlamak için teşekkür ederiz. Bunu söylediniz: * "bir dizinin mutasyona uğratılması hiç bir nesne içermez" *; Bu konuda biraz referans verebilir misiniz? Genel olarak dizilerden mi bahsediyorsunuz yoksa sadece bu özel listeden mi (sadece Doğru/Yanlış değerleri değiştirdiğimiz)? Dahası: bu Java'da ters performans üretecek mi? –
@KurtBourbaki (Bu arada ben bir hat-line profiler başlatmaya çalışıyordum, ama başarılı olmadı.) Genel olarak listelerden bahsediyordum ve ben de item atamasını kastettim. ('[].append 'bellek ayırma ile sonuçlanabilir, ancak bu liste nesnesinin kendisi tarafından gizlenir) –
Yani bu daha hızlıdır, çünkü yeni tamsayılar ayırmak yerine' Doğru 'veya' Yanlış 'değerleri atarız, değil mi? Java hakkında bir şey biliyor musun? E.g .: bit vektörü boole dizisinden daha verimli olur mu? –