Сравнение скорости Python и C++
Бэкендер
Есть миллион причин любить Python (особенно если вы дата-сайентист). Но насколько Python отличается от низкоуровневых языков, таких как Си и C++? В этой статье я собираюсь сделать сравнение скорости Python и C++, на очень простом примере.
Мы будем генерировать все возможные k-меры ДНК, для фиксированного
значения «k». О том, что такое k-меры, я расскажу чуть позже. Этот пример был выбран потому, что многие задачи обработки и анализа данных связанные с геномом, считаются ресурсоёмкими. Поэтому, многие дата-сайентисты связанные с биоинформатикой, интересуются C++ (в дополнение к Python).
Важное замечание: цель этой статьи не сравнить скорость С++ и Python когда они наиболее эффективны. Код предлагаемых программ можно сделать гораздо более быстрым. Цель этой статьи — сравнить два языка, используя один и тот же алгоритм и код.
Введение в k-меры ДНК
ДНК — это длинная цепь нуклеотидов. Эти нуклеотиды могут быть четырёх типов: A, C, G и T. У вида Homo Sapiens около 3 миллиардов пар нуклеотидов. Вот небольшой кусок ДНК человека:
ACTAGGGATCATGAAGATAATGTTGGTGTTTGTATGGTTTTCAGACAATT
Чтобы получить из него k-меры нужно разбить строку на части:
ACTA, CTAG, TAGG, AGGG, GGGA и т. д.
Эти последовательности из четырех символов называются k-меры длина которых равна четырём (4-меры).
Задача
Мы сгенерируем всё возможные 13-меры. Математически — это перестановка с проблемой замены. Следовательно мы имеем 4 в степени 13 (67 108 864) вариантов 13-меров.
Сравнение скорости Python и С++
Мы будем использовать один и тот же алгоритм для двух языков. Код на обоих языках намеренно написан аналогично и просто. Я не использовал сложные структуры данных и сторонние библиотеки. Вот код программы на Python:
def convert(c):
if (c == 'A'): return 'C'
if (c == 'C'): return 'G'
if (c == 'G'): return 'T'
if (c == 'T'): return 'A'
print("Start")
opt = "ACGT"
s = ""
s_last = ""
len_str = 13
for i in range(len_str):
s += opt[0]
for i in range(len_str):
s_last += opt[-1]
pos = 0
counter = 1
while (s != s_last):
counter += 1
# Следующая строка выводит результаты
# print(s)
change_next = True
for i in range(len_str):
if (change_next):
if (s[i] == opt[-1]):
s = s[:i] + convert(s[i]) + s[i+1:]
change_next = True
else:
s = s[:i] + convert(s[i]) + s[i+1:]
break
# Следующая строка выводит результаты
# print(s)
print("Number of generated k-mers: {}".format(counter))
print("Finish!")
Выполнение этой программы займет 61.23 секунды. За это время сгенерируется 67 миллионов 13-меров. Чтобы не увеличивать время работы программы я закомментировал код выводящий результаты (25 и 37 строки). Если вы захотите запустить этот код и отобразить результаты, имейте ввиду, что это будет очень долго. Чтобы остановить выполнение программы вы можете нажать на клавиатуре CTRL+С.
Теперь посмотрим тот же алгоритм на языке C++:
#include
#include
using namespace std;
char convert(char c)
{
if (c == 'A') return 'C';
if (c == 'C') return 'G';
if (c == 'G') return 'T';
if (c == 'T') return 'A';
return ' ';
}
int main()
{
cout << "Start" << endl;
string opt = "ACGT";
string s = "";
string s_last = "";
int len_str = 13;
bool change_next;
for (int i=0; i<len_str; i++)
{
s += opt[0];
}
for (int i=0; i<len_str; i++)
{
s_last += opt.back();
}
int pos = 0;
int counter = 1;
while (s != s_last)
{
counter ++;
// Следующая строка выводит результаты // cout << s << endl; change_next = true; for (int i=0; i<len_str; i++) { if (change_next) { if (s[i] == opt.back()) { s[i] = convert(s[i]); change_next = true; } else { s[i] = convert(s[i]); break; } } } } // // cout << s << endl; cout << "Number of generated k-mers: " << counter << endl; cout << "Finish!" << endl; return 0; }Следующая строка выводит результаты

В таблице указаны результаты тестов для 13, 14, и 15-меров.
После компиляции, этот код выполнится за 2.42 секунды. Получается что Python требуется в 25 раз больше времени на эту задачу. Я повторил эксперимент с 14 и 15-мерами (это можно указать на 12 строке в Python и на 22 в C++) Теперь мы видим, что производительность этих двух языков, при выполнении одной и той же задачи, значительно различается.
Я повторюсь, обе программы далеки от идеала и могут быть значительно опимизированы. Например, мы не использовали параллельные вычисления на CPU или GPU. Но для таких задач это необходимо. Также мы не храним результаты. Хотя управление памятью в Python и C++ значительно влияет на производительность.
Этот пример и тысячи других задач, подтверждают, что дата-сайентистам стоит обращать внимание на C++ и подобные ему языки, когда нужно работать с большими массивами данных или требующими большой производительности процессами.
Источник: https://tproger.ru/translations/sravnenie-skorosti-python-i-c/