Сравнение скорости 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/