LINUX.ORG.RU

Функциональная языкометрия

 расчет факториала


2

3

Поскольку, как всем известно, основное предназначение различных функциональных ЯП состоит в расчете факториалов, давайте померяемся - какой ЯП это делает быстрее (при условии что делает правильно)? Естественно имеет значение машина на которой идет счет.

Условия такие - надо посчитать 10000! и вывести его в 16ти-ричном виде (буквочки маленькие), без всяких '0x' вначале и какой то служебной лабуды в конце. Что бы не постить прстыни, для контроля правильности ответа предлагается использовать md5sum. Вот как это выглядит на втором питоне:

$ python -c 'print hex(reduce( long.__mul__, range(1,10000+1), 1L ))[2:-1]' | md5sum
3de6339590fbdf0a1c0ae2f2b820f8bf  -

Вот однострочник, выводящий модель проца, частоту и время работы (я привожу несколько примеров для доступных мне машин):

$ ssh host1 "less /proc/cpuinfo | grep 'model' | tail -n 1; less /proc/cpuinfo | grep 'cpu MHz' | tail -n 1; time python -c 'print hex(reduce( long.__mul__, range(1,10000+1), 1L ))[2:-1]' | md5sum"
model name      : AMD FX(tm)-8320 Eight-Core Processor           
cpu MHz         : 1400.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.058s
user    0m0.048s
sys     0m0.008s

-------------------------------------------------
model name      : Intel(R) Core(TM)2 CPU         U7500  @ 1.06GHz
cpu MHz         : 798.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.301s
user    0m0.256s
sys     0m0.024s

--------------------------------------------------
model name      : Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
cpu MHz         : 1600.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.042s
user    0m0.040s
sys     0m0.000s

--------------------------------------------------
model name      : AMD Phenom(tm) 9550 Quad-Core Processor
cpu MHz         : 1100.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.083s
user    0m0.068s
sys     0m0.012s

---------------------------------------------------
model name      : AMD Phenom(tm) 9850 Quad-Core Processor
cpu MHz         : 2506.801
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.123s
user    0m0.118s
sys     0m0.004s

----------------------------------------------------
model name      : Intel(R) Core(TM)2 Quad  CPU   Q9450  @ 2.66GHz
cpu MHz         : 2506.801
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.124s
user    0m0.118s
sys     0m0.006s

----------------------------------------------------
model name      : AMD Opteron(tm) Processor 6174
cpu MHz         : 2506.801
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.120s
user    0m0.119s
sys     0m0.002s

----------------------------------------------------
model name      : Intel(R) Xeon(R) CPU           X5670  @ 2.93GHz
cpu MHz         : 1600.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real    0m0.120s
user    0m0.060s
sys     0m0.004s

Я к чему предлагаю померяться - только что обнаружил в соседнем треде, что вечный-тормоз-питон в таком тесте на порядок(!) обогнал священную-корову-лисп;-)))

Предлагайте свои решения на других ЯП (хаскель очень интересен;-))

★★★★★
Ответ на: комментарий от AIv

ВОт тут Функциональная языкометрия (комментарий) Вы заявили «в задаче основные тормоза в hex» что несколько не вяжется с вот этим «в python версия с hex работает в 2 раза быстрее, чем версия без hex»

это моё утверждение некорретно, корретное, при использовании haskell главные тормоза в hex. В питоне тоже так бы было, если бы hex не был сишным builtin-ом, или там определенные оптимизации в рантайме, я не знаю питон на том уровне, чтобы сказать правильно.

В купе с неоправданным надуванием щек и хамством, у меня возникает острое желание послать Вас, Саша, в игнор-лист.

ну знаешь после Функциональная языкометрия (комментарий) неоправдано надуть щеки тяжело, ну и где хамство я тоже не знаю, если покажешь буду осторожнее. Вот честно я не знаю как ответить на тот комментарий нормально т.к. это или слишком некорректная формулировка, или непонимание того, что является сишной функцией или как работают рантаймы языков. После того комментария любую толковую дискуссию можно автоматически прекращать.

Почему я не должен этого делать, кроме того что мы коллеги?

например, потому что в случае неотправления меня в игнор лист, ты можешь получить дельные комментарии про ЯП.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

а сравнивать haskell и python без hex не интересно, 0.05 против 0.45 в пользу haskell.

1 к 1.7 же, или можно существенно быстрее: T.putStrLn . toLazyText . decimal ?

btw в изначальной задаче можно и на обычных строках, не сильно отстать: развернуть в [Word8] и упростить showHex => на 35-40% процентов дольше питона

anonymous
()
Ответ на: комментарий от anonymous

1 к 1.7 же, или можно существенно быстрее: T.putStrLn . toLazyText . decimal ?

нельзя в т.к. нужно hexadecimal, а там баг зарепорченный благодаря этому треду. Т.е. можно, но без оптимизаций, но без них нельзя, т.к. в Text используется stream fusion, который заточен под оптимизацию и без неё жуткий тормоз, плюс для таких размеров данных у toLazyText неудачный размер буффера, нужно toLazyTextWith 65536, т.к. иначе глазами видно, как IO тормозит.

qnikst ★★★★★
()
Ответ на: комментарий от Harald

говорят, GMP быстрее, чем BIGNUM из OpenSSL, просто влом было разбираться с ним

Похоже, правду говорят:

less /proc/cpuinfo | grep 'model' | tail -n 1; less /proc/cpuinfo | grep 'cpu MHz' | tail -n 1; time ./test_factorial_gmp 10000 | md5sum
model name	: Intel(R) Core(TM)2 Duo CPU     T7250  @ 2.00GHz
cpu MHz		: 2001.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real	0m0.023s
user	0m0.016s
sys	0m0.004s
против твоего
less /proc/cpuinfo | grep 'model' | tail -n 1; less /proc/cpuinfo | grep 'cpu MHz' | tail -n 1; time ./test_factorial_openssl 10000 | md5sum
model name	: Intel(R) Core(TM)2 Duo CPU     T7250  @ 2.00GHz
cpu MHz		: 2001.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real	0m0.042s
user	0m0.032s
sys	0m0.004s
Для сравнения:
 time python -c 'print hex(reduce( long.__mul__, range(1,10000+1), 1L ))[2:-1]' | md5sum
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real	0m0.079s
user	0m0.064s
sys	0m0.008s

Разброс где-то +-7ms.

Код:

#include <stdio.h>
#include <gmp.h>

void gmpFactorial( mpz_t result, unsigned int n )
{
    unsigned int i;

    mpz_set_ui(result, 1);
    for( i = 1; i <= n; i++ ) {
        mpz_mul_ui(result, result, i);
    }
}

int main( int argc, char ** argv )
{
    unsigned int n = 0;
    mpz_t result;

    if(argv[1]) {
        sscanf(argv[1], "%d", &n);
    }
    else {
        printf("Usage: test_factorial_gmp <n>\n");
        return 1;
    }

    mpz_init(result);
    gmpFactorial(result, n);
    gmp_printf("%Zx\n", result);
    mpz_clear(result);

    return 0;
}

gag ★★★★★
()
sysctl hw.{model,cpuspeed}; time python -c 'print hex(reduce( long.__mul__, range(1,10000+1), 1L ))[2:-1]' | md5
hw.model=Intel(R) Core(TM)2 Duo CPU L9400 @ 1.86GHz
hw.cpuspeed=1867
3de6339590fbdf0a1c0ae2f2b820f8bf
    0m0.16s real     0m0.16s user     0m0.03s system
beastie ★★★★★
()
Ответ на: комментарий от qnikst

_без hex_ не интересно, 0.05 против 0.45

Это комментировал, здесь hexadecimal не нужен. И на этих данных существенную разницу с toLazyTextWith что-то не могу заметить.

anonymous
()
Ответ на: комментарий от anonymous

у меня как-то так:

import Data.List
import qualified Data.Text as T
import qualified Data.Text.Lazy.IO as T
import qualified Data.Text.Lazy.Builder as T
import qualified Data.Text.Lazy.Builder.Int as T
import qualified Data.Text.Lazy.Encoding as T
import qualified Data.ByteString.Lazy as B

main = print {- T.putStrLn . (T.toLazyTextWith 64229) . T.hexadecimal-}
  (foldl' (*) (1::Integer) [1..100000::Integer])
qnikst@localhost ~/tmp/lor $ \time -v ./fac > /dev/null
	Command being timed: "./fac"
	User time (seconds): 2.01
	System time (seconds): 0.01
	Percent of CPU this job got: 96%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.08
qnikst@localhost ~/tmp/lor $ \time -v python -c 'print reduce( long.__mul__, range(1,100000), 1L )' > /dev/null
	Command being timed: "python -c print reduce( long.__mul__, range(1,100000), 1L )"
	User time (seconds): 13.00
	System time (seconds): 0.61
	Percent of CPU this job got: 99%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:13.61
qnikst@localhost ~/tmp/lor $ \time -v python -c 'print hex(reduce( long.__mul__, range(1,100000), 1L ))' > /dev/null
	Command being timed: "python -c print hex(reduce( long.__mul__, range(1,100000), 1L ))"
	User time (seconds): 5.78
	System time (seconds): 0.56
	Percent of CPU this job got: 99%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:06.34

С выводом в decimal:

\time -v ./fac > /dev/null
	Command being timed: "./fac"
	User time (seconds): 2.07
	System time (seconds): 0.05
	Percent of CPU this job got: 99%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.12

btw в изначальной задаче можно и на обычных строках, не сильно отстать: развернуть в [Word8] и упростить showHex => на 35-40% процентов дольше питона

а можно сделать примитивный буффер выдернуть примитивное число если оно storable и пройтись по нему, сдампив все биты в буффер, получится сишка с неким оверхэдом на RTS. но зачем :)

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

10000! - я про изначальные данные

anonymous
()
Ответ на: комментарий от anonymous

согласен, видать когда с hexadecimal разбирался что попутал.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

чистое gmp приведенное gag

qnikst@localhost ~/tmp/lor $ \time -v ./a.out 10000 > /dev/null
	Command being timed: "./a.out 10000"
	User time (seconds): 0.01
	System time (seconds): 0.00
	Percent of CPU this job got: 62%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.01
	Average shared text size (kbytes): 0

только результат не совпадает.

qnikst ★★★★★
()
Ответ на: комментарий от Manhunt

Скорее всего, увидели бы познания отдельно взятых регистрантов и анонимусов в дискретной математике. Хороший алгоритм на басике вдрызг уделает прямолинейную реализацию на asm+sse.

OMG, надо же, факториал можно не просто тупым перемножением вычислять :)

Вы про это?
http://ru.wikipedia.org/wiki/Факториал#.D0.A0.D0.B0.D0.B7.D0.BB.D0.BE.D0.B6.D...

Только при чём тут дискретная математика?

Harald ★★★★★
()
Ответ на: комментарий от qnikst

У хекса при нормальной реализации и обработке данных изначально лежащих в двоичном формате алгоритмическая сложность О(N), у умножения бигнумов ЕМНИП что то вроде О(N**2), поэтому как там в хацкеле умудрились сделать тормоза в этомб месте - я ХЗ и вообще в ауте.

Если хотите безнаказанно и морально оправданно дуть щеки, то не лажате так как с хексом, вопросов нет. Тут есть товарищей которые не ошибаются, но они почему то обычно корректны, и Вы к ним не относитесь. Или уж если лажаете, таку нефига щеки дуть, ятакщитаю;-)

Насчет ФФИ - ИМНО в питоне любой пук это то же самое что вызов из сторонней С-шной библиотеки (с точностью до каких то оберток типа тех что свиг вешает, но их может и не быть). Все «нативные» ср-ва питона сделаны через С, можно открыть питон АПИ и убедится (за исключением высокоуровневой хрени которая уже на самом питоне написана). Если это не так, и я заблуждаюсь - оченно интересно послушать в чем (ну тока не надо терминологических спороффф).

AIv ★★★★★
() автор топика
Ответ на: комментарий от Harald

Вы про это?

Я про это: http://gmplib.org/manual/Factorial-Algorithm.html , и в частности про «Karatsuba and higher algorithms»

Только при чём тут дискретная математика?

Притом, что используемый аппарат является подразделом дискретной математики (и одновременно подразделом теории чисел).

Manhunt ★★★★★
()
Ответ на: комментарий от beastie

Во, спасибо.

Сижу с телефона, неудобно вечером проанализирую тредд:-)

AIv ★★★★★
() автор топика
Ответ на: комментарий от Manhunt

ну про алгоритм Карацубы я знаю, даже лабу по нему вроде делал, а вот насчёт разложения факториала на простые множители сегодня только узнал

Harald ★★★★★
()

Короче, всё уже изобретено до нас:

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

int main(int argc, char* argv[])
{
	if (argc != 2) {
		printf("Usage: %s <number>\n", argv[0]);
		return 1;
	}
	mpz_t result;
	mpz_init(result);
	mpz_fac_ui(result, strtoul(argv[1]));
	gmp_printf("Factorial is %Zd\n", result);
	mpz_clear(result);
}

mpz_fac_ui() - реализация факториала в libgmp

Harald ★★★★★
()
Ответ на: комментарий от AIv

У хекса при нормальной реализации и обработке данных изначально лежащих в двоичном формате алгоритмическая сложность О(N), у умножения бигнумов ЕМНИП что то вроде О(N**2), поэтому как там в хацкеле умудрились сделать тормоза в этомб месте - я ХЗ и вообще в ауте.

основной вопрос тут в выделении памяти и выводе. Я не готов обсуждать с Вами то как устроен haskell и где и почему возникают сложности, и какие есть варианты их решения, в основном потому, что вам это не надо, да вы и не пытаетесь вчитываться в то, что написано.

Если хотите безнаказанно и морально оправданно дуть щеки, то не лажате так как с хексом, вопросов нет. Тут есть товарищей которые не ошибаются, но они почему то обычно корректны, и Вы к ним не относитесь. Или уж если лажаете, таку нефига щеки дуть, ятакщитаю;-)

ммм.. я не понимаю, почему я должен писать аккуратно, человеку выдавшему подряд следующие комментарии:

Функциональная языкометрия (комментарий)

Функциональная языкометрия (комментарий)

Функциональная языкометрия (комментарий)

и почему этот человек может упрекать других, в «надувании щёк».

Насчет ФФИ - ИМНО в питоне любой пук это то же самое что вызов из сторонней С-шной библиотеки (с точностью до каких то оберток типа тех что свиг вешает, но их может и не быть).

неверно.

вот давайте я уточню: вы считате, что функция + на C дергает ассеблерные функции?

Все «нативные» ср-ва питона сделаны через С, можно открыть питон АПИ и убедится (за исключением высокоуровневой хрени которая уже на самом питоне написана).

это есть обычный built-in функции, но при этом не является ffi вызовом сишной библиотеки.

Если это не так, и я заблуждаюсь - оченно интересно послушать в чем (ну тока не надо терминологических спороффф).

я уже сказал, что для того, чтобы обсудить данную тему нужно понять с чего обсуждать, так же мне нужно смотреть в то, как устроены те или иные функции в питоне, чтобы не «налажать» как с hex. Мне это не сильно нужно и интересно.

P.S. читатели этого треда, если я не прав не стесняйтесь намекнуть мне на это.

qnikst ★★★★★
()
Ответ на: комментарий от Manhunt

и тут эта рекурсия, спасу нету... все равно, хекс гораздо быстрее - взял байт, выдал по таблице два. А у умножения штрассеном же ище данные перетасовывать надо?

AIv ★★★★★
() автор топика
Ответ на: комментарий от adzeitor

И где hex? ;)

- gmp_printf("%Zd\n", result);
+ gmp_printf("%Zx\n", result);

И работает, как и ожидалось, ещё быстрее:

less /proc/cpuinfo | grep 'model' | tail -n 1; less /proc/cpuinfo | grep 'cpu MHz' | tail -n 1; time ./test_factorial_gmp_native 10000 | md5sum -
model name	: Intel(R) Core(TM)2 Duo CPU     T7250  @ 2.00GHz
cpu MHz		: 2001.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real	0m0.004s
user	0m0.000s
sys	0m0.000s

gag ★★★★★
()
Ответ на: комментарий от qnikst

намекаю не стесняясь:

среди ваших утверждений есть истиные

qulinxao ★★☆
()
Ответ на: комментарий от qnikst

это есть обычный built-in функции, но при этом не является ffi вызовом сишной библиотеки.

И в чем же между ними разница? Поглядите что ли исходники питона... Смотрите, есть какой то исходный код, и есть какой то компайлер, который делает из этого исходного кода машкод (очень грубо, тут я не спец). В хацкелде есть скажем исходный код хацкеля, есть компайлер хацкеля, и можно грить про какие то нативные средства хацклея, который компайлером транслируются в какой то хацкелеспецифичный машкод, так? Но на питоне то этого нету. Есть код на С, гцц его прожевал - получилось ядро питона. Есть моя ф-я умножения

double mtmule(double x, double y){ return x*y; }
гцц ее прожевал (с учетом обертки) - получилась либа. Но если я дерну умножение из питона, то в итоге дернется точно такое же умножение, только адрес ф-ии будет не в моей либе а в каком нить libpythonXXX.so

Все «нативные» средства питона реализованы через комбинацию «нативных» средств С. Поэтому (с чего с-но и начался дискасс) - обвинения в использовании забинденных С-шных библиотек несостоятельны, весь питон это одна такая забинденная библиотека + жевалка байт-кода выбирающий какую из С-шных функций за какой дергать.

Вы уж простите меня за корявость изложения -я не имею профильного ИТшного образования, а заканчивал кафедру холодильников;-)

ммм.. я не понимаю, почему я должен писать аккуратно, человеку выдавшему подряд следующие комментарии

Вообще то писать надо всегда аккуратно. Тем более, что ни один из приведенных Вами комментариев мне не принадлежит (один из них вообще Ваш). Вы сами себе аккуратно или неаккуратно пишете?;-)

в основном потому, что вам это не надо, да вы и не пытаетесь вчитываться в то, что написано.

Тут Вы похожи на блондинку, ищущую повод (основание) для ссоры;-)

AIv ★★★★★
() автор топика

Народ, а вам не кажется, что в данном тесте меряется преимущественно скорость преобразований в hex, lowercase и вывода результата?

blexey ★★★★★
()
Ответ на: комментарий от AIv

Попробуйте запустить без hex и пр. У меня разница в проценты.

У Эрланга: 0.083s - получение требуемого результата без вывода против 0.099s - с выводом на i7-930@2.8GHz. Разница >16%.
Это не совсем честные результаты, полученные функцией timer:tc(),
т.к. весь OTP стартует лишних ~1.1s.

blexey ★★★★★
()
Ответ на: комментарий от blexey

Угу, спасибо. Я уже задним числом подумал, что надо было считать что нить вроде 100 000! - ориентировался то в первую очередь на свой старый ноут...

AIv ★★★★★
() автор топика
Ответ на: комментарий от AIv

«Мф.7:6» стих 1

поехали..

Во первых, я так понял, что судя по вашему мнению вы не видите разницы между, например, си и си с ассемблерными вставками. Тогда почему вы говорите, что это сишный код вызавается, а не сразу микрокод процессора? А если бы питон был написан на pascal/haskell, то вы бы говорили, что вызывается pascal/haskell код? А если мы запускаем python в интерпретаторе написанном на go, который транслирует все библиотечные вызовы к интерпретатору c, написанному на pascal, то какие это вызовы будут?

Данная логика является демагогией чистой воды функция написанная на любом ЯП и скомпилированная является частью языка (я их называю С-builtin). И нужно уметь отличать с-builtin функции, которые являются специфичными для языка от библиотечных функций, которые а). используются независимо от runtime (другие языки используют те же библиотеки) б). библиотека работает с данными в своем формате в). библиотека сама занимается аллокацией/реаллокацией объектов г). запуск библиотечных функций блокирует рантайм.

qnikst ★★★★★
()

«Мф.7:6» стих 2

давайте теперь подробно рассмотрим, что за «задачу» Вы предложили:

print hex(reduce( long.__mul__, range(1,10000+1), 1L ))[2:-1]'

в ней проверяется:

  • поддержка в языке генератора(итератора) списка
    data Gen a = Next a (Gen a) | Done
  • возможности подключения gmp/аналога
  • наличия эффективной дампилки в hex
  • принцип работы с IO встроенной операции вывода

Т.е. элементарные вещи, которые есть в любом высокоуровненом ЯП. При этом задача является типовой, тут не проверяется особенности рантайма, особенности модели вычислений, особенности представления данных, поддержка многопоточности, впрочем всех интересных вещей.

qnikst ★★★★★
()

«Мф.7:6» стих 3

по поводу сложности/не сложноти hex и print, Вы можете объяснить следующие результаты для python

[1] print+hex+factorial
[2] print+fatorial
[3] factorial

wall time:
t     [1]         [2]       [3]          [4]
1e0   0.03       0.03      0.03         0.03
1e1   0.03       0.03      0.03         0.03
1e2   0.03       0.03      0.03         0.03
1e3   0.03       0.03      0.03         0.03
1e4   0.07       0.12      0.07         0.07
1e5   6.23±0.03 13.72±0.15 6.37±0.05    6.29±0.13

Сюда же в общем случае при создании hex у тебя нет битового представления числа, у тебя есть только объект чисто и операции (+,-,*,div,mod,..), правда для определенных типов где представление известно их можно оптимизировать.

qnikst ★★★★★
()
Ответ на: комментарий от AIv
True:
...
real    0m1.252s
user    0m0.247s
sys     0m0.040s
False:
0.085s
MD5:
3de6339590fbdf0a1c0ae2f2b820f8bf  -

Собственно, тестируемый код:

-export([showt/0, showf/0, test/0]).

showt() ->
  io:format("~s~n", [
    test()
  ]),
  init:stop().

showf() ->
  {T, _} =timer:tc(?MODULE, test, []),
  io:format("~.3fs~n", [
    T/1000000
  ]),
  init:stop().

test() ->
  binhex(
    binary:encode_unsigned(
      f(10000, 1)
    )
  ).

f(0, A) -> A;
f(N, A) when N>0 -> f(N-1, N*A).

binhex(Binary) -> tl([ h(B) || <<B:4>> <= Binary ]).
% внимание, халтура: tl() просто убирает лидирующий 0 для данного конкретного случая

h(N) when N<0 -> $_;
h(N) when N<10 -> $0+N;
h(N) when N>9 -> $a+N-10;
h(N) when N>15 -> $_.
И запускалка:
#!/bin/bash
erlc +native fact.erl

echo "True:"
time erl -noshell -s fact showt

echo "False:"
erl -noshell -s fact showf

echo "MD5:"
erl -noshell -s fact showt | md5sum

blexey ★★★★★
()
Ответ на: комментарий от anonymous

чё ещё считать???

известны эвристики сложение ( коэф востанавливаются по табличке при коде), умножение на константу+ констатн, возведение в степень??? остальное в явном ввиде через рекурсию с (частичной?) меморизацией . и учитывая современые теробайты :)

qulinxao ★★☆
()
Ответ на: комментарий от qulinxao

интереснее тот же факториал, но в виде серверного приложения, тогда хренова туча клиентов начинают часто запрашивать факториалы разных чисел, с возможностью «отмены» запроса. И считать средний отклик, тут уже есть простор для показа возможностей языка и размышлений о производительности, мемоизации, структур данных.

qnikst ★★★★★
()

Я к чему предлагаю померяться - только что обнаружил в соседнем треде, что вечный-тормоз-питон в таком тесте на порядок(!) обогнал священную-корову-лисп;-)))

Привет Пример из соседнего треда:

(bench
     (let P (native "@" "malloc" 'N 24)
        (finally
           (prog
              (native "libgmp.so" "__gmpz_clear" NIL P)
              (native "@" "free" NIL P))
           (native "libgmp.so" "__gmpz_init" NIL P)
           (native "libgmp.so" "__gmpz_fac_ui" NIL P 10000)
           (native "libgmp.so" "__gmpz_get_str" 'S 0 16 P))))
0.001 sec
(md5 (pack @ "^J"))
-> "3de6339590fbdfa1cae2f2b820f8bf"
$ less /proc/cpuinfo | grep 'model' | tail -n 1; less /proc/cpuinfo | grep 'cpu MHz' | tail -n 1
model name	: Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz
cpu MHz		: 1600.000

anonymous
()
model name	: AMD Opteron(TM) Processor 6272                 
cpu MHz		: 2100.145
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real	0m0.114s
user	0m0.110s
sys	0m0.003s
model name	: Intel(R) Xeon(R) CPU E5-2680 0 @ 2.70GHz
cpu MHz		: 2701.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real	0m0.061s
user	0m0.060s
sys	0m0.000s
model name	: Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz
cpu MHz		: 1200.000
3de6339590fbdf0a1c0ae2f2b820f8bf  -

real	0m0.085s
user	0m0.064s
sys	0m0.016s
SAA ★★★
()
Ответ на: комментарий от anonymous

Вот это труЪ-лисп решение! Дёрнуть нативную библиотеку на Си и выдать результат за превосходство своей священной коровы.

Так и запишем: без сторонних библиотек ЛNСП ни на что не годен. Даже в таких примитивных задачках.

anonymous
()
Ответ на: комментарий от anonymous

А че ж не дернуть, если библиотека для того и существует?

без сторонних библиотек ЛNСП ни на что не годен

да без проблем, что-то типа

(hex (apply * (range 1 10000)))

а как будет выглядеть сишное решение типа Функциональная языкометрия (комментарий) без использования сторонних библиотек? В тысячу строк уложешся?

anonymous
()
Ответ на: комментарий от Harald

тормозит больше чем в два раза:

real 0m0.056s

Без множества прогонов и на таких маленьких интервалах это выглядит не очень убедительно. Хотя бы потому что у меня, например, time python -c 'print()' скачет на 24%. Правда, кое-какая активность в системе есть...

Потом C добавляет некоторый оверхед типа функций исполняемых перед main() и после него (всякие atexit итп). А ещё линкер... Короче, на малых величинах time доверять нельзя.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

То да. Я уже задним числом сообразил, что надо было считать 100 000! - но у меня ноут такое жевал бы долго, а ждать было некогда.

AIv ★★★★★
() автор топика
Ответ на: «Мф.7:6» стих 1 от qnikst

Уффф... лан, по порядку.

вы не видите разницы между, например, си и си с ассемблерными вставками.

В посл. 5-10 что ли лет асм не нужен (для числодробилок) - гцц все делает лучше человека.

Теперь с-но главное. Как вот это:

Данная логика является демагогией чистой воды функция написанная на любом ЯП и скомпилированная является частью языка (я их называю С-builtin).

сочетается вот с этим:

возможности подключения gmp/аналога

??? Потому что по Вашему первому утверждению, про демагогию, long.__mul__ является частью питона, точно такой же как int.__mul__ (никаких доп модулей не подключается), а по второму утверждению вдруг откуда то взялся gmp как ВНЕШНЯЯ библиотека O_O. «Вы батюшка или крестик снимите, или трусы оденьте»(с)

Ну и с-но главное - для любой программы написанной на связке С/C++-питон можно выделить уровень абстракции, где от питона останутся только заголовки С-шных исходников «это питон». Для хацкеля так не выйдет? Предлагаю прекратить эту дискуссию как неконструктивную, потому как Ц-буилтин функции, от того что Вы их таковыми считаете/не считаете, по другому работать не будут.

задача является типовой, тут не проверяется особенности рантайма, особенности модели вычислений, особенности представления данных, поддержка многопоточности, впрочем всех интересных вещей.

Я не пойму, если Вам это так неинтересно, то зачем Вы тут постите дцатую простынь?

по поводу сложности/не сложноти hex и print, Вы можете объяснить следующие результаты для python

Не могу, потому что не понимаю что за табличку Вы привели. Если потрудитесь внятно объяснить что там за цифирки - м.б. и смогу.

AIv ★★★★★
() автор топика
Ответ на: для 1000000 моё от qulinxao

Можно ещё более модные алгоритмы использовать ^^

Вот-с, на чистом Ruby: http://pastebin.com/vvseNY3c

less /proc/cpuinfo|grep 'model' |tail -n 1;less /proc/cpuinfo|grep 'cpu MHz'|tail -n 1; ruby -v; time ruby factorial.rb | md5sum
model name      : AMD E1-1200 APU with Radeon(tm) HD Graphics
cpu MHz         : 1400.000
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
39247b214dea7098e8e671e860ecb3f0  -

real    0m33.168s
user    0m32.858s
sys     0m0.164s

(На 1.9.3 раза в три медленнее работает)

lomereiter
()
Ответ на: комментарий от AIv

В посл. 5-10 что ли лет асм не нужен (для числодробилок) - гцц все делает лучше человека.

вы хотябы понимаете, что вы на вопрос, «видите ли вы разницу между красным и синим?» отвечаете «красный не нужен, потому, что у нас все синим красят».

Я не пойму, если Вам это так неинтересно, то зачем Вы тут постите дцатую простынь?

мне не интересно обсуждать эту задачу, мне _было_ интересно обсудить некоторые идиотские высказываения.

Предлагаю прекратить эту дискуссию как неконструктивную, потому как Ц-буилтин функции, от того что Вы их таковыми считаете/не считаете, по другому работать не будут.

я не знаю или я пишу непонятно, или вы читать не умеете/не хотите/не можете, я пока сконяюсь ко второму варианту, и искрене прошу не разубеждать меня.

Не могу, потому что не понимаю что за табличку Вы привели. Если потрудитесь внятно объяснить что там за цифирки - м.б. и смогу.

написано же wall time, написано у первого столбца n (факториал чего считаем), дальше в секундах время работы функций: print+hex+fac, print+fac, hex+fac, fac.

впрочем спасибо этому треду (точнее программам ltrace и strace и сайту stackoverflow поскольку я сначала не поверил результатам) , т.к. я узнал, что в питоне своя тормозная реализация bignum и нашел баг в одной хацкельной либе.

qnikst ★★★★★
()
Ответ на: комментарий от true_admin

мой код 100000! вычисляет за 3.25 сек под 64 бита и за 8.17 сек под 32. Можно начинать 32 vs 64 срач :)

Это более убедительно?

Harald ★★★★★
()
Ответ на: комментарий от Harald

Конечно, тут разброс (дисперсия?) значительно меньше.

true_admin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.