LINUX.ORG.RU

Сравнение производительности доступа к полям структур в Python, Common Lisp и С++

 , cоmmon lisp, , ,


0

2

Помните, я сказал, что постараюсь не писать до конца сентября? Так вот: у меня не получилось :) Кому не нравится тут тег Яр - заверяю, что он не для рекламы (и так все уже знают), а исключительно для удобства: мне по нему удобно искать, а вам его удобно заигнорить. Отношение к Яру здесь такое: я мучаюсь, как мне реализовать объекты Яра. Склоняюсь к тому, что сделать их с опцией «реализовать как defstruct/clos». Но дальше идут тонкости, в которые сейчас не лезу.

Итак, я нашёл тред пиписькометрии 7 - летней давности: https://www.linux.org.ru/forum/development/4535326, и там сравнивалась скорость каких-то циклов. но это неинтересно. Интересно сравнивать скорость доступа к полям объектов хотя бы. Я попробовал. Вот что в итоге вышло (платформа 64 разрядная).

С++

// cpp-benchmark.cpp
#include "stdio.h"
#include <cstdlib>

class test_class {
public:
	int fld1, fld2, fld3, fld4, fld5;
        test_class *next;
};


int inner(test_class *o,int bound) {
    int res=0;
    for (int i=0;i<bound;i++) {
        res += o->fld1;
        o->fld2 = o->fld1;
        o->fld3 = o->fld2;
        o->fld4 = o->fld3;
        o->fld5 = o->fld4;
        o->fld1 = res - 1;
        o = o->next;
        res = res % 16;

    }    
    return res;
}

int main(int argc, char* argv[])
{
    test_class o1;
    test_class o2;
    o1.fld1=1;
    o2.fld1=1;
    o1.next=&o2;
    o2.next=&o1;
    int n = 100*1000*1000;
    int result=inner(&o1,n);
    printf("%d %d\n",o1.fld5,result); // проверяем корректность и чтобы оптимизатор
    // не выкинул неиспользуемый код
    return 0;
}
// EOF
// запускаем:
g++ -O2 -o cpp-benchmark cpp-benchmark.cpp ; echo disassemble inner | gdb cpp-benchmark ; time ./cpp-benchmark 
// листинг пропускаю.

real	0m0.225s
user	0m0.216s
sys	0m0.004s

Лисп на структурах:

;; struct-benchmark.lisp
(in-package :cl-user)

(list
 '#.(restrict-compiler-policy 'safety)
 '#.(restrict-compiler-policy 'debug))
 
(declaim
 (optimize (speed 3) (safety 0) (debug 0)
           (space 0) (compilation-speed 0)))

(defparameter *times* (* 100 1000 1000))

(defstruct test-struct 
  (next nil :type (or null test-struct))
  (fld1 0 :type fixnum)
  (fld2 0 :type fixnum)
  (fld3 0 :type fixnum)
  (fld4 0 :type fixnum)
  (fld5 0 :type fixnum)
  )

(declaim (inline test-struct-fld1 test-struct-fld2 test-struct-fld3 test-struct-fld4 test-struct-fld5 (setf test-struct-fld1) (setf test-struct-fld2) (setf test-struct-fld3) (setf test-struct-fld4) (setf test-struct-fld5)
                    test-struct-next))

(defun inner (o n)
  (declare (type test-struct o))
  (declare (type fixnum n))
  (let ((res 0))
    (declare (type fixnum res))
    (dotimes (i n)
      (incf res (the fixnum (test-struct-fld1 o)))
      (setf (test-struct-fld2 o) (test-struct-fld1 o)
            (test-struct-fld3 o) (test-struct-fld2 o)
            (test-struct-fld4 o) (test-struct-fld3 o)
            (test-struct-fld5 o) (test-struct-fld4 o)
            (test-struct-fld1 o) (- res 1)
            o (test-struct-next o)
            res (mod res 16)))
    res))

(defun main ()
  (let* ((o1 (make-test-struct :fld1 1))
         (o2 (make-test-struct :fld1 1 :next o1))
         res)
    (setf (test-struct-next o1) o2)
    (setf res (inner o1 *times*))
    (format t "~S~%~S~%" (test-struct-fld5 o1) res)))

(let ((*trace-output* *standard-output*))
  (time (main)))
;;;; EOF
;; запускаем
>(load (compile-file "~/py/struct-benchmark.lisp"))
  0.394 seconds of real time
  0.436000 seconds of total run time (0.436000 user, 0.000000 system)
Лисп, но вместо inline ставим notinline - все аксессоры превращаются в полноценные функции. Получаем
real time 3.879 seconds
Лисп на CLOS:
;; clos-benchmark-with-types.lisp
(in-package :cl-user)

(list
 '#.(restrict-compiler-policy 'safety)
 '#.(restrict-compiler-policy 'debug))
 
(declaim
 (optimize (speed 3) (safety 0) (debug 0)
           (space 0) (compilation-speed 0)))

(defparameter *times* (* 100 1000 1000))

(defclass test-class-3 ()
  ((fld1 :initarg :fld1 :accessor test-class-3-fld1)
   (fld2 :accessor test-class-3-fld2)
   (fld3 :accessor test-class-3-fld3)
   (fld4 :accessor test-class-3-fld4)
   (fld5 :accessor test-class-3-fld5)
   (next :initarg :next :accessor test-class-3-next)))

(defun inner (o n)
  (declare (type fixnum n))
  (declare (type test-class-3 o))
  (let ((res 0))
    (declare (type fixnum res))
    (dotimes (i n)
      (incf res (the fixnum (test-class-3-fld1 o)))
      (setf (test-class-3-fld2 o) (the fixnum (test-class-3-fld1 o))
            (test-class-3-fld3 o) (the fixnum (test-class-3-fld2 o))
            (test-class-3-fld4 o) (the fixnum (test-class-3-fld3 o))
            (test-class-3-fld5 o) (the fixnum (test-class-3-fld4 o))
            (test-class-3-fld1 o) (the fixnum (- res 1))
            o (test-class-3-next o)
            res (mod res 16)))
    (print res)
    res))

(defun main()
  (let* (
         (o1 (make-instance 'test-class-3 :fld1 1))
         (o2 (make-instance 'test-class-3 :fld1 1 :next o1))
         res)
    (setf (test-class-3-next o1) o2)
    (setf res (inner o1 *times*))
    (format t "~S~%~S~%" (test-class-3-fld5 o1) res)))

(let ((*trace-output* *standard-output*))
  (time (main)))
#|
6.115секунд
|#

python:

# ~/py/oop-benchmark.py
import time

__times__ = 100*1000*1000

class TestClass3(object):
  
    def __init__(self):
        self.fld1 = 1
        self.fld2 = 0
        self.fld3 = 0
        self.fld4 = 0
        self.fld5 = 0
        self.next = self

def inner(o,count):
    res = 0
    for i in xrange(count):
        res += o.fld1
        o.fld2 = o.fld1
        o.fld3 = o.fld2
        o.fld4 = o.fld3
        o.fld5 = o.fld4
        o.fld1 = res - 1
        o = o.next;
        res = res % 16
    return res

def my_main():
    o1 = TestClass3()
    o2 = TestClass3()
    o1.next = o2
    o2.next = o1
    res = inner(o1,__times__)
    print '%s' % o1.fld5
    print '%s' % res

my_main()

# запуск:
#time python oop-benchmark.py 
#266666656
#3
#real	0m51.031s
#user	0m50.696s
#sys	0m0.052s
FreePascal
{oop-benchmark.fpc}
{$mode ObjFPC}
const n=100*1000*1000;
type
  PTest = ^TTest;
  TTest = object
  public
    fld1, fld2, fld3, fld4, fld5: Integer;
    next: PTest;
  end;

function inner(o: PTest; bound: Integer): Integer;
var i: Integer;
begin
  Result:=0;
  for i:=0 to bound-1 do with o^ do begin
    Result:=Result+fld1;
    fld2:=fld1;
    fld3:=fld2;
    fld4:=fld3;
    fld5:=fld4;
    fld1:=Result-1;
    o:=next;
    Result:=Result mod 16;
  end;
end;

var
  o1, o2: TTest;
  b: Integer;
begin
  o1.fld1:=1; o1.next:=@o2;
  o2.fld1:=1; o2.next:=@o1;
  b:=inner(@o1,n);
  WriteLn(o1.fld5,' ',b);
end.
{

fpc -O3 oop-benchmark.fpc
Free Pascal Compiler version 2.6.4+dfsg-4 [2014/10/14] for x86_64
Copyright (c) 1993-2014 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling oop-benchmark.fpc
Linking oop-benchmark
/usr/bin/ld.bfd: warning: link.res contains output sections; did you forget -T?
36 lines compiled, 0.1 sec 
1 warning(s) issued
den73@deb8:~/py$ time ./oop-benchmark
266666656 3

real	0m1.810s
user	0m1.776s
sys	0m0.008s
}

cython, pypy

##########
# test.pyx file

import cython

cdef class TestClass:

    cdef public unsigned int fld1, fld2, fld3, fld4, fld5
    cdef public object next
    
    def __cinit__(self):
        self.fld1 = 1
        self.fld2 = 0
        self.fld3 = 0
        self.fld4 = 0
        self.fld5 = 0
        self.next = self

@cython.overflowcheck(False)
@cython.cdivision(True)
cdef inner(TestClass o, count):
    cdef unsigned int res = 0, i
    for i in range(count):
        res += o.fld1
        o.fld2 = o.fld1
        o.fld3 = o.fld2
        o.fld4 = o.fld3
        o.fld5 = o.fld4
        o.fld1 = res - 1
        o = o.next;
        res = res % 16
    return res

def main():
    cdef TestClass o1, o2
    o1 = TestClass()
    o2 = TestClass()
    o1.next = o2
    o2.next = o1
    res = inner(o1, 100_000_000)
    print('%s' % o1.fld5)
    print('%s' % res)

##########
# setup.py file

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

# to compile a module:
# python setup.py build_ext --inplace

extensions = [
    Extension('test', ['test.pyx'],
              extra_compile_args=['-O3'])
]

setup(name = 'access attrs benchmark',
      ext_modules = cythonize(extensions, annotate=True),
)

#########
# main.py file

from test import *
main()

# Запуск с помощью pip 
# 1. Создать ТРИ файла, исходник которых дан выше
# 2. В этой директории:
python setup.py build_ext --inplace
time python main.py

# Результаты:
real	0m0.306s
user	0m0.304s
sys	0m0.004s

$ time pypy oop-benchmark.py 
266666656
3

real	0m0,761s
user	0m0,736s
sys	0m0,020s

EMACS Lisp - несколько быстрее Питона.

★★★★★

Последнее исправление: den73 (всего исправлений: 17)

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

Результат в целом соответствует g++ -O0. Оптимизатор у g++ в подобных ситуациях хорош.

В посте текст паскалевого исходника дублируется.

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

Я отвечаю себе на очень простой вопрос: есть тип данных «структура». ...
Насколько быстро его можно заставить работать в Лиспе

Проблема твоего подхода к испытаниям в том что именно быстрый доступ к «полям» объекта компилятор CL обеспечиват для «лямбд» и замыканий. См. допустим код pandoric{let,-get,-set} в коде написаном для LoL

А структуры и CLOS сделаны по возможности быстрыми из=за возможной «горячей» замены кода инкрементным компилятором. И их некоректно сравнивать с С/C++ исключающим такую возможность :(

antares0 ★★★★
()
Последнее исправление: antares0 (всего исправлений: 1)
Ответ на: комментарий от den73

перепроверять не надо, т.к. текст за end. игнорируется.

Абсолютно верно.
Также из выхлопа пропадет предупреждение:

oop-benchmark.fpc(36,6) Warning: Misplaced global compiler switch
Его тоже можно удалить из поста.

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

На самом деле, нисколько не ограничено. У CL вообще только одна проблема - это устаревшая стандартная библиотека, но и то, все компенсируется другими либами.

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

volatile, это, в первую очередь memory barrier, запрет реордеринга инструкций, ну и запрет на оптимизацию доступа вкупе с этим, конечно

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

Вот смысл ему отвечать?

Он манипулятор/провокатор.

Задает провокационные вопросы, да просто тупо хреново сформулированные.

Играет на людских слабостях, чтобы в этой мутной воде что-то для себя выловить. Сам не хочет, не умеет и не будет напрягается самому понять/сделать.

Оно тебе и вообще кому-то надо?

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

Структуры в SBCL не поддерживают горячую замену, они заточены на быстроту:

; disassembly for INNER
; Size: 88 bytes. Origin: #x234730FA
; 0FA:       31C9             XOR ECX, ECX                    ; no-arg-parsing entry point
; 0FC:       31DB             XOR EBX, EBX
; 0FE:       EB44             JMP L1
; 100: L0:   498B700D         MOV RSI, [R8+13]
; 104:       4801CE           ADD RSI, RCX
; 107:       488BCE           MOV RCX, RSI
; 10A:       498B700D         MOV RSI, [R8+13]
; 10E:       49897015         MOV [R8+21], RSI
; 112:       498B7015         MOV RSI, [R8+21]
; 116:       4989701D         MOV [R8+29], RSI
; 11A:       498B701D         MOV RSI, [R8+29]
; 11E:       49897025         MOV [R8+37], RSI
; 122:       498B7025         MOV RSI, [R8+37]
; 126:       4989702D         MOV [R8+45], RSI
; 12A:       488BF1           MOV RSI, RCX
; 12D:       4883EE02         SUB RSI, 2
; 131:       4989700D         MOV [R8+13], RSI
; 135:       498B4005         MOV RAX, [R8+5]
; 139:       4C8BC0           MOV R8, RAX
; 13C:       4883E11E         AND RCX, 30
; 140:       4883C302         ADD RBX, 2
; 144: L1:   4839FB           CMP RBX, RDI
; 147:       7CB7             JL L0
; 149:       488BD1           MOV RDX, RCX
; 14C:       488BE5           MOV RSP, RBP
; 14F:       F8               CLC
; 150:       5D               POP RBP
; 151:       C3               RET
А вот для один из сишных:
   0x0000000000400650 <+0>:	test   %esi,%esi
   0x0000000000400652 <+2>:	jle    0x40068c <_Z5innerP10test_classi+60>
   0x0000000000400654 <+4>:	xor    %ecx,%ecx
   0x0000000000400656 <+6>:	xor    %eax,%eax
   0x0000000000400658 <+8>:	nopl   0x0(%rax,%rax,1)
   0x0000000000400660 <+16>:	mov    (%rdi),%edx
   0x0000000000400662 <+18>:	add    $0x1,%ecx
   0x0000000000400665 <+21>:	add    %edx,%eax
   0x0000000000400667 <+23>:	mov    %edx,0x4(%rdi)
   0x000000000040066a <+26>:	mov    %edx,0x8(%rdi)
   0x000000000040066d <+29>:	mov    %edx,0xc(%rdi)
   0x0000000000400670 <+32>:	mov    %edx,0x10(%rdi)
   0x0000000000400673 <+35>:	lea    -0x1(%rax),%edx
   0x0000000000400676 <+38>:	mov    %edx,(%rdi)
   0x0000000000400678 <+40>:	cltd   
   0x0000000000400679 <+41>:	mov    0x18(%rdi),%rdi
   0x000000000040067d <+45>:	shr    $0x1c,%edx
   0x0000000000400680 <+48>:	add    %edx,%eax
   0x0000000000400682 <+50>:	and    $0xf,%eax
   0x0000000000400685 <+53>:	sub    %edx,%eax
   0x0000000000400687 <+55>:	cmp    %esi,%ecx
   0x0000000000400689 <+57>:	jne    0x400660 <_Z5innerP10test_classi+16>
   0x000000000040068b <+59>:	retq   
   0x000000000040068c <+60>:	xor    %eax,%eax
   0x000000000040068e <+62>:	retq   
Т.е. Си видит, что сначала пишем fld2, а потом читаем. Он пишет в fld2, а на чтении экономит, считая, что мы прочитаем то же, что записали. Лисп так не делает, а честно выполняет то, что сказали (можно считать, что поле помечено как volatile). Можно долго рассуждать, почему так, но я не настолько компетентен, чтобы сказать точно, связно ли это с отличием семантики Си от семантики лиспа или просто с плохим оптимизатором.

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

Впрочем я устал «нести добро», как давеча lovesan.

Хотите дискутировать с этим «любознательным» пареньком - ваш выбор.

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

Если уж переходить в режим офтопа, то у лиспа очень плохо с инструментами. Для сей вон какой выбор IDЕ, а тут один емакс. Вот тут на lispworks-Hug очередной товарищ захотел писать IDE для CL, а вот один из ответов ему:

At work I use C#/C++ and Visual Studio extensively. Especially for C# the IDE has some fantastic features that I miss when using SLIME. I came from that background and while learning Emacs was pretty frustrating at first, I've gotten over most hurdles and have been using SLIME for about four or five years now. I've spliced in some custom SLIME init code using neotree, and purpose-mode to get dedicated inspector buffers, frames, and such. After becoming more proficient with Emacs, I want to say that I fully believe you can make a visual-studio quality Common Lisp IDE within Emacs, and that it isn't -that- far off. And I really believe this is the way to go, because fracturing the already (relatively) small lisp community to start a new editor I believe is pretty fruitless. Furthermore, I think it's more productive to get a genuine, concrete list of what you want out of the IDE that is missing from SLIME, rather than the general «it doesn't feel right to me».

For example, here's a couple of what I want: * Treating ASDF files as a 'project' and having better ASDF integration with SLIME in general to be able to specify 'build' and 'debug' operations * Customization of the SLIME inspector (similar to DebuggerDisplay attribute in C#) * Multiple inspectors * More sane window/buffer layout

Т.е. годы идут, сообщество тает, а воз и ныне там. В то время, как для других языков есть рефакторинги, решарперы, автоматическое и на лету преобразование Java-Kotlin и пр.

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

Нет на, это невозможно.

годы идут, сообщество тает

Наглая дезинформация. С каким хреном оно тает? Факты?

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

рефакторинги, решарперы, автоматическое и на лету преобразование

Все это г по сравнению с swank/slime/slimv/... Ты даже не это не удосужился осилить, околачиваясь столько лет в лиспе.

рефакторинги, решарперы

А эти слова вообще БРЕД и родились и нужны как раз в ваших недоязыках.

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

Структуры в SBCL не поддерживают горячую замену

Они поддерживают горячую замену использующего их кода. Это тоже влиет на скорость работы. Лямбды/Замыкания же молча перемалываются компиляторм в «фарш» который становится скрепляющим звеном между кодом вызова и телом замыканияю Поэтому такой вариант работает быстрее.

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

В данном случае не влияет - везде полный inline, в цикле никаких вызовов функций нет. Ты посмотри на ассемблерный листинг - там вполне очевидно, что лисп просто делает больше работы.

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

В общем, на теме ставлю галку - сейчас потратил ещё 20 минут на попытку использовать numba, но не осилил. Если кто-нибудь предложит вариант реализации на numba (там jit в llvm и прочие умности), будет интересно сравнить. В numbа кстати, есть и рекорды. Хотя проект пока нестабилен и за последние два года сильно поменялся.

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

Уверен? Насколько я помню, компилятор просто не оптимизирует обращение к volatile переменной и не читает её из регистров

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

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

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

Можно прочитать старое значение даже после записи нового

Я и не спорю.

Generally, there are memory barrier operations available on platforms (which are exposed in C++11) that should be preferred instead of volatile as they allow the compiler to perform better optimization and more importantly they guarantee correct behaviour in multi-threaded scenarios; neither the C specification (before C11) nor the C++ specification (before C++11) specifies a multi-threaded memory model, so volatile may not behave deterministically across OSes/compilers/CPUs)

volatile не добавляет барьера (по крайней мере в C). лавсанчик не прав

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

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

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

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

Лол :-) Единственное, что на Лиспе писать нельзя - это драйвера устройств :-) На бесплатных Лиспах нельзя сделать нормальный GUI, такой, какой можно сделать на каком-нибудь Qt5, например :-) Хотя под Mac можно писать на Clozure CL обычные GUI приложения :-) Писать на Лиспе очень просто :-) Единственное условие для этого - знания Лиспа :-) Отсюда следует, что «писать сложно» тем, кто Лисп не знает :-) И, судя по всему, ты в числе тех, кто его не знает :-) Зато пытаешься рассуждать о том, что хорошо писать на Лиспе :-) Это не удивительно, ибо таких экспертов с мнениями полный интернет :-) Лол :-)

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

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

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

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

Не пишут, потому что не знают, а не потому, что неудобно :-) Точнее говоря, неудобно, потому что не знают :-) Для таких полуграмотных уместнее слово «не способны», а не «неудобно» :-) Лол :-)

серверный софт на лиспе

Кстати говоря, это интересно с т.з. безопасности :-) Если посмотреть на баг-репорты какого-нибудь известного сервера, написанного на «удобном» Си или цепепе, наверняка всплывёт большая куча багов класса «buffer overflow» или типа того :-) Так что серверный софт на Лиспе - это интересно :-) Думаю, его таки пишут какие-нибудь секретные программисты :-) Им, поверь, удобно на Лиспе писать :-)

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

мало ли кому что удобно. просто тормозной и жрущий ресурсы софт на серверах не нужен. внезапно. потому пишут на С и всё нормально работает.

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

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

Ага :-) Поэтому если посмотреть на услуги любого хостера, то на первом месте там тормозной PHP, затем Ruby или Python :-) Хотя, бывает и Node.js :-)

потому пишут на С и всё нормально работает.

Единицы пишут «серверный софт» на C :-) Даже всякие популярные соцсети с миллионами и миллиардами пользователей написаны на PHP (по крайней мере, изначально было так) :-) А если ты про крупнейший поисковик - так это уже отдельная история :-)

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

php 7 весьма шустр, всякие питоны ему и в подметки не годятся, а еще у него синтаксис пижже

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

Почему секретные?

Потому что открытого серверного софта на Лиспе мало :-) Есть Hunchentoot, есть cl-http :-) Сколько в публичном доступе фаерволов или роутеров, написанных на Лиспе? :-) А может быть SSH-сервер есть на Лиспе в публичном доступе? :-)

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

... и думаю, что обработку протоколов сети на лиспе не пишут. ...

пишут

... серверный софт на лиспе не пишут....

пишут

... я знаю, как устроен лисп ...

не знаешь

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

свидетельство твоей некомпетентности в большинстве областей. Узкий специалист подобен флюсу ... (ц)

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

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

В душе вы большой любитель питона, я бы сказал, латентный питонист.

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

Даже всякие популярные соцсети с миллионами и миллиардами пользователей написаны на PHP

да и флаг им в руки. софт такого рода меня никогда не интересовал ни как программиста, ни как юзера. и да, он тормозит и жрёт ресурсы. сайтовые машины на C и С++ существуют и работают в сотни раз быстрее и экономнее по памяти и процу.

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

Вот ты говоришь, что я ни нихя не понимаю, а я всего лишь хочу сделать «класс», который по выбору можно реализовать через CLOS (сохранение с заменой инстансов) или через defstruct (с эффективностью). Потому-то я и сравнивал CLOS с defstruct-ом. Опять скажешь, я хочу странного? Тут и анонимусы горазды писать, что я всегда задаю бредовые вопросы по CL.

Допустим так. Тогда почему именно такой макрос с подпись (С) Texas Instruments 1987 присутствует в CLX? Он называется def-clx-class.

А потому, что я рублю фишку. То, что в CL есть отдельно классы и отдельно структуры - это просто косяк в стандарте. На самом деле должен был быть один «класс» и опции к нему. Косяк, видимо, вызван тяжёлым наследием прошлого, которое наложило на лисп отпечаток. Я этот косяк вижу и действую, чтобы его исправить. Потому что лично мне неприемлемо, что CLOS почти такой же тормозной, как Питон, при том, что структур хватает почти всегда. И вот типичная секто-тема:

https://groups.google.com/forum/#!topic/comp.lang.lisp/21ir7zO4MG4

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

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от Iron_Bug

Мда, на лицо cognitive bias. Вот уж не ожидал такого предубеждения от вас. Вы когда вызываете такси, всегда требуете болид формулы 1, чтоб домчал за минуту там, где обычная машина проедет за час? И чтобы впереди ехал асфальтоукладчик, потому что дороги не идеальны?

Желательно, чтобы при этом маршрутки исчезли, так как они мешают ехать и у них, вообще, за рулем не шумахеры.

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

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

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

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 3)
Ответ на: комментарий от den73

def-struct-or-class

Ну, немного подрихтовал (т.е. добавил свои еретические библиотеки и немного привёл в соответствие со стандартом). Пока так:

https://bitbucket.org/budden/iar/src/9d46f7769ae3544f0df40577a8b764db8437eab5...

(надо, правда, вставить ещё копирайт от TI, из к-рого я это взял). Дальше сильно поменяется, поэтому будет неюзабельно вне контекста Яра.

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

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

Python
my_main()

Обычно в Питоне это оформляют так:

def main():
    ...

if __name__ == "__main__":
    main()

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

вовсе станет очевидна абсолютная ненужность пистона

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

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

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

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

Она просто расстроена, что ей не предложили работу, где надо писать на Python ;)

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

А ничего, что в python структур нет? Синтаксис с точкой - всего лишь синтаксический сахар для доступа к элементам словаря объекта. И в результате сравнивается производительность структур с производительностью хэш таблицы.

Если указать __slots__, то словаря объекта (__dict__) не будет. Так должно быть оптимальнее, но скорее всего это крохи, да и использовать слоты — значит мухлевать, они не идиоматичны для ООП питона.

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

Вот из той же оперы. Только без Лиспа, т.к. не объектный

А как же CLOS??

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

Объясни, как померять и я это сделаю. luajit в принципе и так страшная сила (во всяком случае, на таких бенчмарках).

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

Ну где ж ты раньше был. Я именно это и искал :( Теперь, как честный офицер, я должен ему сделать пулл-реквест, при том, что для меня вопрос уже исчерпан.

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

А, так это ты и есть? Готов принять три теста на CL?

Есть две тонкости :)

1. Нужно тестировать на том же железе (чтобы не пересчитывать все результаты на новом), а тот ноут валяется полудохлый — аккумулятор накрылся, GUI отвалился. В принципе, для теста оба варианта не помеха, но несколько ломает, собираться тестировать придётся дольше :)

2. То, в чём тестировать, желательно, чтобы было доступно в Ubuntu (можно в PPA), чтобы не ломать голову над установкой и настройкой незнакомых систем.

Но, в общем, давай, давно тесты не пополнялись :)

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