Pull to refresh
68
0.1
Сергей @onegreyonewhite

Специалист

Send message
А чем куб разворачиваете? Kubspray'ем?
Уже лучше. И вы молодец, что адекватно реагируете на критику (пусть даже она действительно была резковата с моей стороны). Я думаю за комментарии вам стоит почитать это руководство.

1. Если документируете, то лучше бы использовать так:
'''
Программное переключение выключателя

:param val: -- Положение выключателя (0 - выкл, 1 - вкл, 2 - переключение)
:type val: int
:rtype: None
'''

2. «Старайтесь реже использовать подобные комментарии.» — цитата из руководства выше, с которой я солидарен. Такой комментарий легко может скрыться, потому что находится за границами экрана + можно его банально пропустить глазами, когда дошёл до конца строчки кода.
3. Вот только так и пишите комментарии.

Ко всему прочему, судя по всему вы забыли, что у вас нет метода .auto(), а есть ._auto(). А если вы ещё проверите код flake'ом, то он ещё может ругнуться на неиспользуемый аргумент v в этой же функции.
if (val==2):    self.value=not self.value
else:           self.value=val

Первая мысль при виде этого — «где мой миксер? глаза — вы мне больше не нужны!»
Ещё такое ощущение, что вы все 3 вида комментариев учились использовать.
За что вы так с людьми, которые будут это читать?
Ладно PEP-8, но совесть-то у вас есть?

P.S.: Простите, если я излишне эмоционален. На днях пришлось много Python-кода исследовать в одном проекте заказчика, и я ещё не отошёл от травмы.
Артефакты только через API, а библиотек под это нет. Не то чтобы это неудобно, но руками curl дёргать и парсить вывод то ещё удовольствие. Молчу уже о том, что релизы автоматом создаются на tag, что тоже не всегда правильно. Мне нравится Gitlab, больше чем github, но эта фича одно расстройство.
Круто! Спасибо за идею.
Я вообще не чувствительный, но мне вдруг стало так жалко программы, которые запускаются в Docker'е. Теперь не удивлюсь, если прога в докере сойдёт с ума.
Если проект в какой-нибудь госконторе, то это почти типичное явление. Я уж молчу про 1С (7.7) и небольшие магазины, ТСЖ и т.п. К сожалению, часто вижу небольшие фирмы, где всё так устроено и руки чешутся им помочь (хотя возможно это аллергия на old-school-legacy).
У них (сайт для проверки) там баг (или просто не учли). Запись в кеше сохраняется и повторный запрос всегда отвечает «ОК». С телефона не могу проверить, но судя по всему они с клиента запрос делают, а значит повторная проверка или проверкая адреса с долгим ttl может быть неправильная.
Мне кажется, что писать «это шутка, не используйте» нужно заголовочным ярким красным шрифтом в начале статьи.
При этом обязательно найдётся тот, кто пропустит и начнёт применять, оправдывая тем, что читал на Хабре.
Я думаю это было его первое свидание с linux. Добавлю ещё, что если уж используется debian, то собрать образ автоматически не составит труда, при помощи debootstrap и chroot.
А для совсем энтузиастов, можно задействовать gentoo (что, кстати, многие и делают): если выпилить всё, что не нужно конечному устройству, то получиться небольшой оптимизированный под будущее железо дистрибутив. Правда в последнем варианте, будет собираться капец как долго.
И вообще, я не вижу никакой практической пользы в создании объекта вектора динамически. Зачем вы вообще это делаете?

Эксперимент. В рамках Django это нормальное явление, поэтому так и сделали.
Нельзя использовать free для удаления объектов, созданных через new! free нужно использовать только для освобождения памяти, выделенной через malloc. Это же азы, ну как так то, ребята?

Да, это мой косяк в силу недостатка знания. В пн попробую реализовать через malloc и обновлю статью.
Если кратко. Я взял этот код, благо википедия помогла его запустить. Я посмотрел на два сгенерированных листинга и увидел PyDict_SetItemString и PyDict_SetItem. Далее, я загуглил PyDict_SetItemString и оказалось, что эта функция создаёт пистон-объект из си-строки. Вторая же функция принимает пистон-строку, да мало того, что пистон-строку — он ещё «кэширует» все литералы.

Вот это интересно. Надо будет в пн попробовать добавить в скрипт и посмотреть что выйдет.
Пациент пошел ставить минусы всем моим комментам. Это настолько глупо.
Глупо жаловаться на то, что вам ставят минусы. Возможно это связанно с тем, что вы вместо того, чтобы услышать людей, доказываете какую-то свою правоту:
К чему написан очередной нелепый набор слов?

Я сообщил о несостоятельности бенчмарков и сравнения… Ну во-первых, что измеряют эти тесты?.. И это очевидно. Какое отношение бенчмарк, где создание dict занимает 99% времени измеряет оверхед на list? Никаким.

Кроме поверхностных выводов, вы статью читали (не только сам скрипт)? Вопрос стоял вполне себе конкретно: нужно было обработать один большой массив словарей (не map'ов, не структур, а конкретно словарей типа dict из Python), да и сделать это так, чтобы потом не пришлось танцевать с бубном, чтобы использовать этот массив в Python-коде. Цели переписать всё на C++ не было.
Что из этого следует и зачем это было написано? Кто-то говорил о какой-то инициализации данных? Нет.

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

Более того, основной посыл статьи чётко обозначен:
После этого эксперимента, мы решили сильно не заморачиваться с поддержкой Python 2.7 и переделкой каких-либо частей приложений на C++, просто потому что оно того не стоит. Всё уже написали до нас, нам остаётся это лишь правильно применить для решения конкретной задачи.

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

Так я и не говорил, что такие числа по времени будут у всех на всех процессорах. Я не совсем понял какие выводы следовало бы сделать?
Но я все равно хочу попробовать вынести весь C++ код в .h и посмотреть как это повлияет.

До этого было -O3. Решили плавно наращивать и смотреть по отзывам. Разницы в целом не было, кроме -O0.

Намёк на то, что можно было вместо free() использовать del data_list? Есть ли от этого какая-то практическая польза?

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


Цель же статьи не сравнить C++ и Python, а сравнить возможность и необходимость решения задачи, используя те или иные возможности C++ расширения.

Спасибо за заметку. В понедельник попробую это проверить в сочетании с тем, что предложил iCpu по поводу полного переноса кода с вектором в C++.

Нет, не описал. «Мы используем -O1» — это не аргумент.

Наверно мало в тексте было написано:
Очень хочется, чтобы можно было собирать *.whl для проекта и чтобы это всё завелось на практически любой системе

Были проблемы при установке на машинах со слегка отличной архитектурой, поэтому поставили флаг -O1. В любом случае, наличие большей оптимизации производительности не принесло или добавило её незначительно (меньше 0.01с), поэтому мы используем для сборки такой уровень оптимизации. Как я уже написал в тексте, была цель сделать максимально приближено к условиям реальной эксплуатации.

Что было бы, если бы вы не контейнер втянули, а сам словарь написали на С++, а в питон пробросили методы?

Это вот вопрос уже интереснее, но не думаю, что профит был бы намного больше. Хотя думаю стоит проверить и такой вариант, для чистоты эксперимента. Впрочем, такой вариант использовать станет очень неудобно, поэтому будет не соблюдено главное требование — удобство при разработке. Т.к. этот код работать будет в библиотеке, то наверняка его захочется потом перегрузить и т.п. В случае с python/cython это решается просто, а с чистым C++ будет много лишней возни, как, например, наследование и т.п. Можно конечно только одну функцию вставки/обработки/сортировки использовать, но не настолько большой профит будет (да и не факт, что будет).
Код для вектора тоже было бы вежливо предоставить. А так мы сравниваем бульдога с носорогом. Погодите-ка… Это сравнение питоновых list и vector?

У Python нет vector. Это биндинг из Cython, который берет из
<vector>
класс vector
оригинальный код из Cython
cdef extern from "<vector>" namespace "std" nogil:
    cdef cppclass vector[T,ALLOCATOR=*]:
        ctypedef T value_type
        ctypedef ALLOCATOR allocator_type

        # these should really be allocator_type.size_type and
        # allocator_type.difference_type to be true to the C++ definition
        # but cython doesn't support deferred access on template arguments
        ctypedef size_t size_type
        ctypedef ptrdiff_t difference_type

        cppclass iterator:
            T& operator*()
            iterator operator++()
            iterator operator--()
            iterator operator+(size_type)
            iterator operator-(size_type)
            difference_type operator-(iterator)
            bint operator==(iterator)
            bint operator!=(iterator)
            bint operator<(iterator)
            bint operator>(iterator)
            bint operator<=(iterator)
            bint operator>=(iterator)
        cppclass reverse_iterator:
            T& operator*()
            reverse_iterator operator++()
            reverse_iterator operator--()
            reverse_iterator operator+(size_type)
            reverse_iterator operator-(size_type)
            difference_type operator-(reverse_iterator)
            bint operator==(reverse_iterator)
            bint operator!=(reverse_iterator)
            bint operator<(reverse_iterator)
            bint operator>(reverse_iterator)
            bint operator<=(reverse_iterator)
            bint operator>=(reverse_iterator)
        cppclass const_iterator(iterator):
            pass
        cppclass const_reverse_iterator(reverse_iterator):
            pass
        vector() except +
        vector(vector&) except +
        vector(size_type) except +
        vector(size_type, T&) except +
        #vector[input_iterator](input_iterator, input_iterator)
        T& operator[](size_type)
        #vector& operator=(vector&)
        bint operator==(vector&, vector&)
        bint operator!=(vector&, vector&)
        bint operator<(vector&, vector&)
        bint operator>(vector&, vector&)
        bint operator<=(vector&, vector&)
        bint operator>=(vector&, vector&)
        void assign(size_type, const T&)
        void assign[input_iterator](input_iterator, input_iterator) except +
        T& at(size_type) except +
        T& back()
        iterator begin()
        const_iterator const_begin "begin"()
        size_type capacity()
        void clear()
        bint empty()
        iterator end()
        const_iterator const_end "end"()
        iterator erase(iterator)
        iterator erase(iterator, iterator)
        T& front()
        iterator insert(iterator, const T&) except +
        iterator insert(iterator, size_type, const T&) except +
        iterator insert[Iter](iterator, Iter, Iter) except +
        size_type max_size()
        void pop_back()
        void push_back(T&) except +
        reverse_iterator rbegin()
        const_reverse_iterator const_rbegin "crbegin"()
        reverse_iterator rend()
        const_reverse_iterator const_rend "crend"()
        void reserve(size_type)
        void resize(size_type) except +
        void resize(size_type, T&) except +
        size_type size()
        void swap(vector&)

        # C++11 methods
        T* data()
        void shrink_to_fit()


Почему всего лишь -O1? Хотя бы уж -Ofast -ftree-vectorize -msse2

А в чём собственно проблема? Я описал почему мы используем так.

Information

Rating
3,992-nd
Location
Sacramento, California, США
Date of birth
Registered
Activity