LINUX.ORG.RU

Python vs Lisp. Расстановка точек


0

1

питон:

den@ira-desktop:~/work/test$ time python -O test.py 
('answer: ', 39)

real	0m33.035s
user	0m32.890s
sys	0m0.084s
den@ira-desktop:~/work/test$

clisp:

den@ira-desktop:~/work/test$ time clisp test.lsp
39

real	2m44.491s
user	2m42.970s
sys	0m1.464s
den@ira-desktop:~/work/test$

def test():
    r = 0
    for i in range(0, 10000):
        for j in range(0, 10000):
            r = (r + (i * j) % 100) % 47
    return r
r = test()
print("answer: ", r)
(defun test ()
    (setq r 0)
    (dotimes (i 10000 r)
        (dotimes (j 10000 r)
            (setq r (mod (+ r (mod (* i j) 100)) 47))
        )
    )
)

(write (test))

а теперь докажите, что лисп не тормознутое УГ

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

напиши лучше и сравни результат

Там в самих тестах смысла мало.

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

> Спасибо, но у меня есть чем заняться более полезным.

если ты не можешь бегло посмотреть их решения и увидеть узкие места - то может твоя оценка необъективна?

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

> Почитай классиков наших, они выправляют это

У меня дома библиотека в 6 тыс томов. Читал не всё, но всех основных классиков пожалуй да, не помогает :(

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

> а меценатствовать под это мероприятие ты будешь?

тогд пиши корректно - mingw vs SBCL, а не лисп против С

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

>а современная реализация Python - в ~30 раз в лучшем случае.
Тебеж сказали под psyco пускать надо.

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

> если ты не можешь бегло посмотреть их решения и увидеть узкие места

- то может твоя оценка необъективна?


Не надо разбираться в CL, что бы посмотреть лог работы SBCL, где сам SBCL пишет, что разработчик идиот.

archimag ★★★
()

Кто там про фортран заикался - где результаты тестов?

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

> Не надо разбираться в CL, что бы посмотреть лог работы SBCL, где сам SBCL пишет, что разработчик идиот.

т.е. сам код ты не видел? чтд

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

Ну вот тест mandelbrot.
http://paste.lisp.org/display/94596
Все эти варнинги и обобщенная арифметика убирается банально декларациями типов и более продуманным кодом.
Естественно при всем этом говне код от SBCL получается тормознее, чем от жабы, например.

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

> т.е. сам код ты не видел? чтд

Сам код там особо не при чём. Там неверно расставлены декларации, в результате чего SBCL жутко ругается и не может понять, что от него хотят.

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

ничего не знаю, результаты вот они.

Кстати, собрал майкрософтовским компилятором, из Windows SDK 7.0, с /O2, так там получается еще медленнее, где-то примерно на уровне SBCL

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

pyrex кстати не помог

den@ira-desktop:~/work/test$ python test.pyo
Время выполнения функции: 4.598111
('answer: ', 39)

unladen swallow нагло слил

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

> unladen swallow нагло слил

Что значит «слил» - показал непотребное время, упал, не запустился вообще? Какой Unladen - из trunk или Q3?

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

Q4, показал непотребное время, 60 секунд

antony986
() автор топика

SHED SKIN уделал всех, теперь я знаю как сделать быстрый бинарник из питона

den@ira-desktop:~/work/test$ ./test
Время выполнения функции: 0.629477
('answer: ', 39)
antony986
() автор топика

Пример у вас какой-то примитивный. Расстановка точек. Вот реальная вещь - сортировка слиянием. Тут уже можно меряться секундами.

#include <iostream>
#include <cstdlib>
using namespace std;

void Merge(double a[], double aux[], int l, int m, int r)
{
	for (int i = l; i < m; i++) aux[i] = a[i];
	for (int j = m; j < r; j++) aux[j] = a[m + r - j - 1];
	int i = l, j = r - 1;
	for (int k = l; k < r; k++)
	{
		if (aux[j] < aux[i]) a[k] = aux[j--];
		else a[k] = aux[i++];
	}
}

void Sort(double a[], double aux[], int N)
{
	for (int m = 1; m < N; m = m+m)
		for (int i = 0; i < N-m; i += m+m)
		{
			int t = i+m+m; if (t > N) t = N;
			Merge(a, aux, i, i+m, t);
		}
}

void Create(double r[], int size)
{
	srand(time(NULL));
	double k = 1.0 / RAND_MAX;
	for(int i = 0; i < size; ++i) r[i] = rand() * k;
}

bool Check(double r[], int size)
{
	for(int i = 0; i < size - 1; ++i)
	{
		if (r[i] > r[i+1]) { cerr << "error: " << r[i] << " > " <<  r[i+1] << endl; return false; }
	}
	return true;
}

int main()
{
	const int SIZE = 10000000;
	double *r = new double[SIZE], *aux = new double[SIZE];
	Create(r, SIZE);
	Sort(r, aux, SIZE);
	if (!Check(r, SIZE))
		return 1;
	return 0;
}
Процессор 2.4ГГц, gcc -O2
real	0m3.074s
user	0m3.012s
sys	0m0.060s

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

И попробуй под ним запустить живой код... Я имею ввиду хоть тот-же джанго или твистед. И какой профит?

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

Пример у вас какой-то примитивный. Расстановка точек. Вот реальная вещь - сортировка слиянием. Тут уже можно меряться секундами.

Померяемся. Ну и сортировка слиянием - тоже примитивный пример. Тут негде раскрыться всей мощи динамических фич лиспа.

Ваш код на c++:

dvk@localhost ~/tmp $ g++ -O3 -o ms ms.cpp
dvk@localhost ~/tmp $ time ./ms

real	0m3.464s
user	0m3.311s
sys	0m0.144s

Мой код на лиспе:

dvk@localhost ~/tmp $ time sbcl --load ms.lisp --eval "(merge-sort:main :n (expt 10 7))" --eval "(quit)"
This is SBCL 1.0.35.gentoo-r0, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
; loading system definition from
; /usr/share/common-lisp/systems/asdf-binary-locations.asd into
; #<PACKAGE "ASDF0">
; registering #<SYSTEM ASDF-BINARY-LOCATIONS {10031D0681}> as
; ASDF-BINARY-LOCATIONS
; loading system definition from /usr/share/common-lisp/systems/iterate.asd
; into #<PACKAGE "ASDF0">
; registering #<SYSTEM :ITERATE {1003579E81}> as ITERATE
; registering #<SYSTEM :ITERATE-PG {1002C786C1}> as ITERATE-PG
; registering #<SYSTEM :ITERATE-TESTS {1002F4D5C1}> as ITERATE-TESTS
Evaluation took:
  3.664 seconds of real time
  3.650445 seconds of total run time (3.570457 user, 0.079988 system)
  [ Run times consist of 0.006 seconds GC time, and 3.645 seconds non-GC time. ]
  99.62% CPU
  7,310,825,550 processor cycles
  80,000,016 bytes consed
  

real	0m4.717s
user	0m4.492s
sys	0m0.206s

1.05x от времени работы программы на cpp (и плюс 1.1 секунды на компиляцию).

Неплохо, я считаю. Но пример тоже не очень страшный, тут не встретилось проблем для кодогенерации в SBCL (к счастью).

ms.lisp:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (asdf:oos 'asdf:load-op :iterate))

(defpackage #:merge-sort
  (:use #:cl #:iter)
  (:export #:main
           #:ms-sort))

(in-package #:merge-sort)

(declaim (optimize (speed 3) (safety 0) (debug 0) (space 0) (compilation-speed 0)))

(declaim (ftype (function ((simple-array double-float))) ms-sort))
(defun ms-sort (numbers)
  (declare (type (simple-array double-float) numbers))
  (let* ((n (length numbers))
         (aux (make-array n :element-type 'double-float :initial-element 0.0d0)))
    (declare (type fixnum n)
             (type (simple-array double-float) aux))
    (flet ((ms-merge (l m r)
             (declare (type fixnum l m r))
             (iter (for i from l below m)
                   (declare (type fixnum i))
                   (setf (aref aux i) (aref numbers i)))
             (iter (for j from m below r)
                   (declare (type fixnum j))
                   (setf (aref aux j)
                         (aref numbers (the fixnum (- (the fixnum (+ m r)) (the fixnum (+ j 1)))))))
             (iter (with i = l)
                   (with j = (1- r))
                   (for k from l below r)
                   (declare (type fixnum k))
                   (if (< (aref aux j) (aref aux i))
                       (progn (setf (aref numbers k) (aref aux j))
                              (decf j))
                       (progn (setf (aref numbers k) (aref aux i))
                              (incf i))))))
      (iter (for m first 1 then (+ m m))
            (declare (type fixnum m))
            (while (< m n))
            (iter (for i from 0 below (- n m) by (+ m m))
                  (declare (type fixnum i))
                  (ms-merge i (+ i m) (min n (+ i m m))))))))

(declaim (ftype (function ((simple-array double-float)) boolean) check))
(defun check (numbers)
  (iter (for i from 0 below (1- (length numbers)))
        (for next-i from 1 below (length numbers))
        (declare (type fixnum i next-i))
        (always (< (aref numbers i) (aref numbers next-i)))))

(declaim (ftype (function (fixnum) (simple-array double-float)) create))
(defun create (n)
  (iter (with result = (make-array n :element-type 'double-float))
        (for i from 0 below n)
        (declare (type fixnum i))
        (setf (aref result i) (random 1.0d0))
        (finally (return result))))

(defun main (&key (n 1000) print)
  (let ((a (create n)))
    (when print (print a))
    (time (progn (ms-sort a)
                 (unless (check a)
                   (format t "Sorting failed~%"))))
    (when print (print a))
    (check a)))

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

Вы меня простите, конечно. Я не говорю что лисперы такие плохие, просто не понимаю их.
Вот не троллю. Как вы считаете, тот код что вы вот на лиспе показали, он на сколько читаемый? На сколько он удобно читается? А относительно кода на CPP? Мне просто интересно. Не подумайте плохого.

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

Если, как выясняется, со скоростью оно также, как и в С++, то с читаемостью просто беда. Алгоритм прячется за обилием скобок и служебных слов.

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

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

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

Да и код является просто калькой вашего кода.

Или вас смутило, что много слов, но мало пунктуации? Мне, например, не очень хорошо читается ваш cpp'шный исходник (хотя я cpp'шник со стажем).

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

>Только лично моё мнение - в 95% случаев карринг является сигналом на то что ты что-то набыдлокодил.

<troll-mode>Вот он, подход к дизайну в C++</troll-mode>

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

>то с читаемостью просто беда

Если вам это интересно, то можно сделать код покороче и более читаемым. У меня такой цели не стояло, мы здесь мерили быстродействие.

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

>Тот код, который я показал, вполне нормально читается лисперами.

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

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

В коде нет ничего «китайского». Нормальный читаемый но многословный код. Макро-сахар подсластит его и сделает более концентрированным.

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

Так много писали в предыдущей теме, что Лисп можно превратить в C/Java со скобками {} и инфиксной записью, что интересно взглянуть на это дело на практике.

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

Отлично читается! В отличие от C++, у которого алгоритм погреьён под кучей непонятных значков, из которых у половины изменяется значение в зависимости от контекста.

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

> то с читаемостью просто беда. Алгоритм прячется за

обилием скобок и служебных слов.


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

archimag ★★★
()

time ruby 1.rb

answer = 39
ruby 1.rb 38.59s user 0.11s system 83% cpu 46.252 total

time python 1.py

('answer: ', 39)
python 1.py 73.39s user 0.18s system 83% cpu 1:27.82 total

anonymous
()

ClozureCL:

CL-USER> (defun test () 
	   (let ((r 0)) 
	   (dotimes (i 10000 r) 
	     (dotimes (j 10000 r) 
	       (setq r (mod (+ r (mod (* i j) 100)) 47))))))
TEST
CL-USER> (time (test))
(TEST) took 12,469 milliseconds (12.469 seconds) to run 
                    with 2 available CPU cores.
During that period, 12,391 milliseconds (12.391 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
39
CL-USER> 
cathode
()
Ответ на: комментарий от tia

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

Это стихи Пушкина, переложенные на английский язык. Чтение хороших лисповых исходников с утра доставляет эстетическое удовольствие и заставляет задуматься о суете нашей жизни.

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

Дык а я что? Мне то можно, я ещё так молод и могу позволить ошибаться и развиваться в неправильную сторону. Но тв. mv...

Я тоже думал, что мог позволить ошибаться и развиваться в неправильную сторону. Ошибся, развился. А надо было учить жабу или дотнет. Или 1C, вот где реальные бабки. И как-нибудь лет в 40-45, когда middle-age кризис нагрянет, с утреца повешался бы на ёлке, потому что в жизни моей не было Лиспа.

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

Толсто :) И первый, и второй комментарии :)

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

Да, лисп читается отлично. Лисп также очень лаконичный язык.

for (int j = m; j < r; j++) 
    aux[j] = a[m + r - j - 1]; 

 (iter (for j from m below r) 
                   (declare (type fixnum j)) 
                   (setf (aref aux j) 
                         (aref numbers (the fixnum (- (the fixnum (+ m r)) (the fixnum (+ j 1))))))) 
anonymous
()
package test;

public class Main {
    static int dummy = 0;
    static long test() {
        long start = System.currentTimeMillis();
        
        int r = 0;
        for (int i = 0; i < 10000; ++i) {
            for (int j = 0; j < 10000; ++j) {
                r = (r + (i * j) % 100) % 47;
            }
        }
        
        dummy += r;
        
        return System.currentTimeMillis() - start;
    }
    
    public static void main(String[] args) {
        System.out.println("First test: " + test() + " ms");
        System.out.println("Hotting machine...");
        for (int i = 10; i --> 0;) {
            test();
        }
        System.out.println("Hot test: " + test() + " ms");
        System.out.println("dummy: " + dummy);
    }
}
First test: 1277 ms
Hotting machine...
Hot test: 762 ms
dummy: 468

Джава вновь оказалась быстрее Си?

Legioner ★★★★★
()

Зачем это всё? Не занимайся некромантией, пусть займутся другие. Нормальному человек всё стало бы понятно, когда он узнал бы, что гугл выбирает Питон, а не лиспы и прочие ObjectХламы...

P.S.
А ведь реализация на Питоне ещё и очень неоптимальна, можно было бы куда быстрее... Даааа....

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

Это стихи Пушкина, переложенные на английский язык. Чтение хороших лисповых исходников с утра доставляет эстетическое удовольствие и заставляет задуматься о суете нашей жизни.

Мысли о суициде после чтения не посещают? :)

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

> Зачем это всё? Не занимайся некромантией, пусть займутся другие. Нормальному человек всё стало бы понятно, когда он узнал бы, что гугл выбирает Питон, а не лиспы и прочие ObjectХламы...

А еще гугл выбирает C++, а Sun/Oracle/IBM Java, да.

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

А еще гугл выбирает C++, а Sun/Oracle/IBM Java, да.

Ну а что выбирает Черный Властелин до которого что сану что ораклу как пешком до китаю мы скромно умолчим :)

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

Хотя нет, С показал тоже неплохие результаты:

First test: 1133 ms
Hotting...
Hot test: 701 ms
dummy: 468

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

> когда он узнал бы, что гугл выбирает Питон

Вообще-то, гугл чем дальше, тем больше выбирает Java, угу ;)

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

Мысли о суициде после чтения не посещают? :)

Если от высокого слога у кого-то развиваются суицидальные настроения, то на Лиспе ему, к сожалению, не писать.

mv ★★★★★
()

Язык, скорость?! Часто это не главное. Некоторые, вон, и на си с плюсами умеют писать кривой и медленный код.

Кстати, питон меня несколько удивил. Начал недавно пользоваться mercurial. Он в некоторых вещах оказался прозорливее и умнее, чем subversion. Видимо, все же дело в авторах. И в сишных вставках тоже. Если брать что-то большее, чем приведенный тест.

А точки товарищ «расставил» смешно :)

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