Подтвердить что ты не робот

Сохранять читаемость кода при оптимизации

Я пишу научную программу на Python и C с некоторыми сложными алгоритмами физического моделирования. После реализации алгоритма я обнаружил, что существует множество возможных оптимизаций для повышения производительности. Обычные - это предварительные вычисления, получение вычислений вне цикла, замена простых матричных алгоритмов более сложными и другими. Но возникает проблема. Неоптимизированный алгоритм намного медленнее, но его логика и связь с теорией выглядят намного понятнее и понятнее. Кроме того, сложнее расширить и модифицировать оптимизированный алгоритм.

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

4b9b3361

Ответ 1

Как общее замечание (я не слишком хорошо знаком с Python): я бы предложил вам убедиться, что вы можете легко обменять медленные части "эталонной реализации" на "оптимизированный (например, используйте что-то вроде Strategy pattern).

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

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

Ответ 2

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

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

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

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

Еще одна вещь, о которой вы уже знаете: оптимизация обычно не означает, что shoehorning тонны кода на одну строку источника, возможно, вызывается функцией, аргумент которой является другой функцией, аргументом которой является другая функция, аргумент которой является еще одной функцией. Я знаю, что некоторые делают это, чтобы временно не сохранять значение функции. Но это очень мало (обычно ничего), чтобы ускорить код, и это сука, чтобы следовать. Я знаю, никаких новостей для вас.

Ответ 3

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

Это не обязательно так.

Вам нужно выяснить, что именно он проводит много времени и почему?

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

Вот пример того, что я имею в виду.

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

Ответ 4

def whatYouShouldDo(servings, integration_method=oven):
    """
        Make chicken soup
    """
    # Comments:
    # They are important. With some syntax highlighting, the comments are
    # the first thing a new programmer will look for. Therefore, they should
    # motivate your algorithm, outline it, and break it up into stages.
    # You can MAKE IT FEEL AS IF YOU ARE READING TEXT, interspersing code
    # amongst the text.
    #
    # Algorithm overview:
    # To make chicken soup, we will acquire chicken broth and some noodles.
    # Preprocessing ingredients is done to optimize cooking time. Then we 
    # will output in SOUP format via stdout.
    #
    # BEGIN ALGORITHM
    #
    # Preprocessing:
    # 1. Thaw chicken broth.
    broth = chickenstore.deserialize()

    # 2. Mix with noodles
    if not noodles in cache:
        with begin_transaction(locals=poulty) as t:
            cache[noodles] = t.buy(noodles)  # get from local store
    noodles = cache[noodles]

    # 3. Perform 4th-order Runge-Kutta numerical integration
    import kitchensink import *  # FIXME: poor form, better to from kitchensink import pan at beginning
    result = boilerplate.RK4(broth `semidirect_product` noodles)

    # 4. Serve hot
    log.debug('attempting to serve')
    return result
    log.debug('server successful')

также см. http://en.wikipedia.org/wiki/Literate_programming#Example

Я также слышал, что это то, что http://en.wikipedia.org/wiki/Aspect-oriented_programming пытается помочь, хотя я на самом деле не смотрел на него. (Кажется, это просто фантастический способ сказать: "Положите свои оптимизации и свои отлаживатели и ваш другой мусор за пределы функции, которую вы пишете".)