Numpy быстрее чистого C?

У меня есть следующий код C. На моей машине это время составляет около 13 секунд.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    clock_t begin = clock();

    double d = 0;

    for (int i = 0; i < 1e9; i++) {
        d = 1 + rand() * 5 > 10 ? 4 : rand();
    }

    clock_t end = clock();
    double time_spent = (double) (end - begin) / CLOCKS_PER_SEC;

    printf("%f", time_spent);
    return EXIT_SUCCESS;
}

Но эта непростая операция, я измеряю доли секунды!

a = np.random.randn(1000, 1000)
b = np.random.randn(1000, 1000)
c = a.dot(b)

Как это возможно, учитывая, что они выполняют одинаковый объем работы (1e9 операций)? Распараллеливание numpy ??

На какой ОС вы работаете? Если вы работаете в Linux, запустите команду top из командной строки при выполнении операции numpy и визуально проверьте, сколько ядер используется. Хотя я подозреваю, что numpy не использует параллелизм без вашего явного указания.

Arthur-1 28.11.2018 08:13

Ваша программа на C имеет if посередине, что часто останавливает процессор.

Mark Setchell 28.11.2018 08:15

Вы делаете очень разные операции. Во-первых, ваш Python генерирует псевдослучайные числа 2e6; ваш код C, по крайней мере, 1e9 в дополнение к умножению и сумме, которое выполняют оба кода. Вы бы предпочли поднять тысячу листов бумаги или тысячу ядер? Почему? Разве это не то же самое, тысячи и тысячи?

Amadan 28.11.2018 08:16

попробуйте сделать np.random.randn (31623, 31623)

BishalG 28.11.2018 08:16

В c вы выполняете более 10 ^ 9 операций rand () из-за вашего состояния в цикле.

Nikolaus 28.11.2018 08:24

Опять же ... Совершенно и совершенно бессмысленно обсуждать производительность, если 1) вы не говорите нам, какую систему вы используете, 2) вы не говорите нам, какой компилятор вы используете, и 3) вы не говорите нам какие варианты оптимизации использовались.

Lundin 28.11.2018 10:33

@Lundin: Ваше утверждение о том, что бессмысленно обсуждать производительность без этой информации, противоречит тому факту, что основная причина наблюдаемого поведения OP была правильно диагностирована за два часа до вашего комментария.

Eric Postpischil 28.11.2018 13:42
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
8
7
185
2

Ответы 2

Numpy имеет бэкэнды на нескольких языках, таких как C, C++ и Fortran, как указано в их документах

As Numeric has matured and developed into NumPy, people have been able to write more code directly in NumPy. Often this code is fast-enough for production use, but there are still times that there is a need to access compiled code. Either to get that last bit of efficiency out of the algorithm or to make it easier to access widely-available codes written in C/C++ or Fortran)

Так что, если вы не пишете высокооптимизированный код C, скорее всего, он в любом случае будет медленнее.

Ваши программы работают по-другому. Ваша программа C вызывает randкак минимум10^9 раза. кроме того, у вас есть условия для ваших случайностей.

numpy создает 2 массива 1000x1000, а это только 2x10^6. нет условий на случайное значение. скалярное произведение затем добавляет операции O(n^3) (и создание массива), но очень оптимизировано.

Таким образом, вы в основном сравниваете последовательные вызовы rand в C с гораздо меньшим количеством вызовов randn плюс оптимизированная операция (dot) в python.

Чтобы иметь действительный тест, у вас должны быть 2 программы, выполняющие одни и те же операции.

Вы имеете в виду, что программа numpy выполняет только 1 вызов случайной функции для генерации 10 ^ 6 различных случайных записей?

Arthur-1 28.11.2018 08:15

Матричное скалярное произведение принимает O (n ^ 3), что равно 1e9.

DYZ 28.11.2018 08:16

Но точка находится вдоль общей размерности 1000. Итак, у нас есть два массива в 10 ^ 6, я с вами. Но точка добавляет еще 10 ^ 3 операций. Вернуться на 10 ^ 9

Truman Purnell 28.11.2018 08:16

Numpy, вероятно, сильно оптимизирует точечный продукт для локализации кеша, поэтому я готов поспорить, что его операции 10 ^ 9 выполняются намного быстрее, чем системные вызовы 10 ^ 9 (для случайных) в программе C++.

Arthur-1 28.11.2018 08:18

вы все еще сравниваете разные операции очень. ~10^9rand() вызовы против 10^6nrand() вызовов плюс умножение / создание массива. для реального теста вы должны убедиться, что ваши программы работают точно так же.

hiro protagonist 28.11.2018 08:18

@ Arthur-1 random не является системным вызовом.

DYZ 28.11.2018 08:19

Обратите внимание, что оба кода безоговорочно выполняют сложение 1e9 и умножение 1e9. Вызовы cca 2e9 rand являются наверху этого. Здесь - источник случайного числа glibc - сложение, умножение и побитовое И (для простейшего ГСЧ).

Amadan 28.11.2018 08:22

Глупый, я не знаю, с какой стати я предполагаю, что реализация будет делать системный вызов генератору случайных чисел ОС. Наверное пора спать :)

Arthur-1 28.11.2018 08:24
numpy.dot вызовет базовую библиотеку BLAS в вашей системе, если это возможно.
juanpa.arrivillaga 28.11.2018 08:27

Другие вопросы по теме