LXF134:StarBasic
|
|
|
- Пользовательские функции Добавьте электронным таблицам недостающий функционал
Содержание |
OOo Calc: Оптимизация
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
- После того, как функция написана и работает правильно, надо добиться, чтобы она работала быстро. Александр Маджугин знает, как этого добиться.
В прошлых статьях мы научились создавать пользовательские функции для Calc и делать их работу стабильной и удобной. Но при любых сложных вычислениях есть ещё один важный аспект – это производительность. Если вы создаёте пользовательские функции, ваши вычисления уже можно назвать сложными, так как для простых в большинстве случаев хватает и встроенных функций электронных таблиц.
В этой статье мы начнём говорить об оптимизации вычислений в Calc, затрагивая вопросы оптимизации кода в функциях Basic, применительно к реализации, встроенной в OpenOffice.org. Статья окажется полезной не только тем, кто создаёт пользовательские функции Calc, но и всем, кто занимается разработкой макросов для OOo.
Датчик скорости
Измерять производительность можно двумя способами: по времени вычисления фиксированного количества результатов и по количеству результатов, полученных за фиксированное время. И тот, и другой имеют полное право на существование, но первый обычно удобнее в реализации. Второй же лучше подойдёт для создания тестов производительности.
Посмотрим на следующий код:
Sub Chronometr Dim lStartTime As Long ' Время запуска Dim lResult As Long ' Время работы lStartTime = getSystemTicks MyFunction lResult = getSystemTicks - lStartTime Print lResult End Sub
Он измеряет время однократного вычисления функции MyFunction путём нахождения разности значений счётчика getSystemTicks до вызова функции и после его завершения.
Как правило, одного вычисления недостаточно – какими бы медленными ни были интерпретаторы, скорость всё равно достаточно высока, и шанс, что результатом замера будет 0, весьма велик. Поэтому практически всегда приходится использовать цикл с многократным вычислением функции: чем он длиннее, тем меньше погрешность и накладные издержки измерения. На практике замер должен длиться не меньше 8–10 секунд.
Рассмотрим практический пример, а нашим подопытным станет функция FXOR из предыдущей статьи – Листинг 1. Для измерения скорости её работы преобразуем процедуру Chronometr таким образом:
Sub Chronometr Dim lStartTime As Long ' Время запуска Dim lResult As Long ' Время работы Dim lFuncResult As Long ' Переменная для приёма результата Dim l As Long lStartTime = getSystemTicks For l = 1 To 100000 lFuncResult = FXOR(255,l) Next lResult = getSystemTicks - lStartTime Print lResult End Sub
Мне понадобилось 100 000 шагов цикла для того, чтобы время работы на моём ноутбуке приблизилось к 10 секундам. Если у вас производительная машина, вам может потребоваться больше. Для приёма результата я создал специальную переменную lFuncResult: это не обязательно, но я люблю, чтобы всё было «по-честному». В качестве второго аргумента FXOR я использовал счётчик цикла – это удобно, особенно если время работы вашей функции может зависеть от значения аргументов.
Для повышения честности замера иногда бывает полезно вычислить время холостого хода тестовой процедуры. Просто закомментируйте строку lFuncResult = FXOR(255,l), выполните несколько запусков, и, запомнив время работы процедуры, вычтите его из конечного результата, либо добавьте в начало функции следующий код:
lStartTime = getSystemTicks For l = 1 To 100000 Next lResult = getSystemTicks - lStartTime
Строку lResult = getSystemTicks — lStartTime следует заменить на lResult = getSystemTicks — lStartTime — lResult. Тогда холостой ход будет вычитаться из результата автоматически. Другим спо-собом снижения накладных издержек работы цикла является многократный вызов процедуры внутри него.
Для перегруженных функций важным является ещё и тип используемых в тесте аргументов. Например, вызов FXOR только для целых дал у меня результат около 10 000 миллисекунд, а вызов её же для строк длиной 6 символов дал уже в среднем 47 000 миллисекунд. Старайтесь замерять общую производительность функции в условиях, близких к реальным. Например, если предполагается, что FXOR будет использоваться для целых примерно в 75 % случаев, а для строк средней длиной 6 символов только в 25 % случаев, то код внутри цикла должен выглядеть примерно так:
lFuncResult = FXOR(65535,l) lFuncResult = FXOR(0,l) lFuncResult = FXOR(l,l) sFuncResult = FXOR(“djkely”,”saljcx”)
Эти рекомендации касаются только общей производительности. При оптимизации конкретного участка кода, напротив, следует снизить все издержки на вычисления вне его. Для достижения данной цели используйте знания о структуре кода и конструкции своего алгоритма. Например, при оптимизации обработки строк в нашем примере вообще не стоит вызывать саму функцию FXOR, дабы избежать лишних издержек на перегрузку, которые постоянны. Следует вызывать сразу её подфункцию SXOR. В данном случае это помогает снизить время работы теста почти на 20 %.
Оптимизация кода
Перейдем непосредственно к оптимизации, и начнем с подфункций. Внимательно посмотрим на SXOR. Можно ли здесь что-то улучшить? С первого взгляда – вроде бы нет. Но вот что выйдет, если мы применим лишь пару из самых важных правил опти-мизации:
- Общее решение всегда медленнее решения для частного случая. (Если вы считаете, что такой стиль – дурной тон, то дочитайте, пожалуйста, статью до конца – я вернусь к этому вопросу).
- В первую очередь следует минимизировать количество вычислений внутри цикла.
Какие мы можем выделить частные случаи? Во-первых, когда второй аргумент равен по длине или длиннее первого. В этом случае становится лишней операция деления значения счётчика по модулю длины второго аргумента – он и так не выйдет за пределы строки. Соответственно, вычисление очередного символа результата внутри цикла можно переписать так: sResult = sResult & Chr(ASC(Mid(sFirst,l,1)) XOR ASC(Mid(sSecond,l,1))), минимизировав число операций внутри цикла.
Во-вторых, длина второго аргумента может быть равна одному символу. Здесь вообще становятся не нужны функции Mid и ASC внутри цикла, и операцию нахождения кода символа второй строки можно вынести:
iSC = ASC(sSecond) For l = 1 To lLF sResult = sResult & Chr(ASC(Mid(sFirst,l,1)) XOR iSC) Next
Ну и третий случай – когда второй аргумент короче первого, но длиннее одного символа. Здесь код останется неизменным. В итоге функция примет вид, приведенный в Листинге 2.
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Как видно, функция стала длиннее. В неё добавились новые операции сравнения. Ну, а что же с производительностью? Согласно рис. 1, модификация принесла нам более чем 13 % рост производительности в синтетическом тесте (по 5 000 расчётов для наборов с длиной второго аргумента 1, 3 и 16 символов и длиной первого аргумента 16 символов). При этом худший показатель модифицированной функции всего -2,6 % для третьего случая (15 000 расчётов; длина первого аргумента – 16 символов, а второго – 3). Не такая уж большая потеря, особенно если учесть, что для первого случая (15 000 расчётов; длина первого аргумента – 16 символов, а второго – 1) мы смогли добиться прироста производительности более чем в 30 %.
Для чего я так подробно выполнил, а теперь описываю этот тест? Дело в том, что здесь мы проводили специальную оптимизацию кода, основной проблемой которой является то, что она даёт не только рост производительности для отдельных случаев работы кода, но и (зачастую) снижение производительности для некоторых других.
Такого рода оптимизация хороша тогда, когда мы знаем или можем предположить, как и для чего будет в основном использоваться наша функция. Ориентироваться нужно, конечно, на наиболее вероятные на практике случаи.
Если же достоверные данные об области применения отсутствуют, то руководствоваться необходимо данными синтетических тестов, предполагающих, что все случаи равновероятны. Однако при таком предположении всегда стоит учитывать и результаты наихудших тестов. Так, если мы видим незначительный прирост в синтетическом тесте и сильное падение в одном из специальных, то, вероятно, от такой оптимизации лучше воздержаться, так как никто не может гарантировать вам, что наихудший случай не окажется самым вероятным при практическом использовании, о котором ничего не известно заранее. Более того: я готов спорить на пиво, что именно так оно и будет.
К счастью, таких сложностей лишена общая оптимизация, при которой, как правило, растёт производительность всей функции при любом её использовании. Перейдём к ней.
В общем случае
Для общей оптимизации обычно лучше использовать синтетические тесты, наиболее близкие к реальным условиям. Для примера здесь мы предположим, что наша функция 'FXOR будет использоваться преимущественно следующим образом: в половине случаев оба входящих параметра будут целыми положительными числами, а в половине – строками. Причём для строк известно, что длина первого параметра в среднем будет равна 16 знакам, а длина второго в трети случаев будет равна длине первого (то есть тем же 16 знакам), ещё в трети – одному знаку, и ещё в трети будет переменной от 1 до 4 знаков.
Для эмуляции последней трети случаев использования FXOR со строками применим преобразование значения счётчика к строковому типу – Cstr(l). При этом не забудем добавить строку sFuncResult = Cstr(l) в цикл измерения времени холостого хода тестера, дабы увеличить точность измерения времени работы функции.
Код же внутри цикла измерения может получиться примерно следующим:
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
lFuncResult = FXOR(65535,0) lFuncResult = FXOR(65535,l) lFuncResult = FXOR(0,l) sFuncResult = FXOR(“djkelyqwertyjlkr”,”s”) sFuncResult = FXOR(“djkelyqwertyjlkr”,CStr(l)) sFuncResult = FXOR(“djkelyqwertyjlkr”,”salghkmvtrdljtra”)
Выполним замеры для исходной, неоптимизированной функции. У меня в синтетическом тесте получилось в среднем 28 859 миллисекунд.
Можно переходить к оптимизации. Поочерёдно разберём все использованные приёмы.
Первое, что необходимо сделать – это избавиться от вызова подфункций. Разбиение программы на маленькие законченные блоки в виде функций или процедур очень удобно при написании кода, но сильно сказывается на производительности, так как интерпретатор затрачивает достаточно много времени на помещение процедуры в стек вызовов, инкапсуляцию переменных и другие необходимые для вызова подпроцедуры действия.
Поэтому просто перенесём содержимое наших подфункций NXOR и SXOR в места их вызова из родительской функции FXOR и внесём необходимые изменения в имена переменных. В данном случае это даст нам около 6 % прироста производительности. Если вам кажется, что это немного, то вспомните функцию COMBINE из предыдущей статьи, где вызов подфункции может происходить до 30 раз за вычисление. Здесь время на вызов подфункций и непосредственное вычисление результата распределено приблизительно так, как на диаграмме на рис. 2. Не слишком ли жирный кусок пирога мы отдаём за возможность использовать подфункцию, в условиях нехватки времени?
Далее можно переходить к более тонкой настройке, которая в данном случае сводится к знанию особенностей использования функции и устройства интерпретатора Basic в OpenOffice.org. И это наиболее важная часть данной статьи, так как этих сведений вы не встретите в других публикациях, посвящённых оптимизации кода.
Вспомним, что в функциях Calc невозможно передать какой либо аргумент, опустив один из предшествующих. Следовательно, проверка передачи параметра vFirst является излишней, так как если он опущен, то опущен и параметр vSecond; а значит, код проверки передачи параметров можно изменить на следующий:
If IsMissing (vSecond) Then ' проверяем переданы ли параметры fXOR = “#NOTARG!” ' Аргументов слишком мало Exit Function End If
Далее, применим знание об одной не самой приятной особенности StarBasic. Рассмотрим следующую конструкцию:
If условие1 AND условие2 Then код End If
В большинстве руководств по другим языкам вы прочтёте, что условие2 не будет проверяться, если условие1 ложно, так как в этом случае результат всей конструкции от результата условия2 не зависит – она всё равно останется ложной.
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
В StarBasic это не так: условие2 здесь будет проверено в любом случае, независимо от результата условия1. Поэтому, чтобы не терять производительности, в StarBasic вышеприведённую конструкцию следует переписать так:
If условие1 Then If условие2 Then код End If End If
Проделаем эту операцию с конструкциями If IsNumeric(vFirst) And IsNumeric(vSecond) Then... и If VarType(vFirst)=8 And VarType(vSecond)=8 Then.... То, что получилось в результате этих преобразований, представлено в Листинге 3. Такой код в условиях описанного выше теста станет производительнее ещё приблизительно на 9 %.
Теперь пора сравнить производительность полученной нами функции и функции, приведённой в самом начале статьи.
Сравнивать будем в трёх тестах – только числа, только строки и синтетический тест. Для последнего используем вышеприведённые условия. Для чисел закомментируем строки с вызовом функции со строковыми параметрами и увеличим число проходов с 5 000 до 50 000. Для теста со строками закомментируем строки с числовыми параметрами функции.
Результат тестирования на моём ноутбуке представлен на рис. 3.
Как видите, даже оптимизируя достаточно простую, и, с первого взгляда, грамотно написанную функцию, не имеющую длительных или вложенных циклов, мы добились относительно неплохих результатов, ускорив её работу в целом более чем на 20 %, а в отдельных случаях – и более чем на 35 %. На практике же, особенно со сложными функциями, можно добиваться гораздо более впечатляющего результата.
Общие принципы
Наконец, давайте рассмотрим некоторые общие принципы оптимизаций применительно к StarBasic. Во-первых, следите за переменными – старайтесь объявлять их явно. Операции с необъяв ленными переменными происходят медленнее. В самоконтроле хорошо помогает инструкция Option Explicit, добавленная в начало модуля. Контролируйте типы и избегайте их преобразования.
Используйте константы вместо переменных там, где это возможно. Константы быстрее переменных. Используйте более экономные конструкции циклов. StarBasic поддерживает конструкцию перебора всех элементов массива For Each, хотя она и не документирована. Данный цикл не использует счётчик и потому быстрее цикла For To Step. Синтаксис конструкции таков:
For Each Var In Arr … Next
Конструкция перебирает все элементы массива Arr, помещая их последовательно в переменную Var. Используйте её всегда, когда в цикле не важен порядок перебора его элементов. Несмотря на то, что данная конструкция, как правило, перебирает элементы массива по порядку, теоретически он может быть нарушен – не стоит забывать об этом.
Минимизируйте количество операций внутри циклов. Они повторяются многократно и потому очень сильно влияют на производительность. А если вы вызываете внутри цикла другую функцию или процедуру Basic, то не удивляйтесь, что ваш код работает медленно. Вызов подпроцедур – задача очень затратная по времени. Если ваша ставка – скорость, старайтесь, по возможности, вообще отказаться от вызова стороннего кода Basic.
Отдельную тему для разговора представляют собой условия. Сами по себе они предоставляют огромный простор для оптимизации, а в отношении рассматриваемой реализации Basic – тем более. Об особенности, связанной с проверкой незначащих условий, мы уже говорили выше. А что можно сделать ещё?
Во-первых, можно попробовать отказаться от условий вообще, заменив их численным решением или выбором из массива. Простейший пример, известный по шуточному тесту, где значение переменной необходимо заменить с 1 на 2 и наоборот, даёт в численном решении пятикратный рост производительности, то есть код
Val = 3 – Val
в пять раз быстрее, чем
If Val = 1 Then Val = 2 Else Val = 1 End If
Однако это, безусловно, частный случай, и заменить условие на численное решение возможно далеко не всегда. Совсем другое дело – выбор из массива: таких решений можно найти множество, и так как в них выявляется ещё одна особенность рассматриваемой реализации Basic, разберём его подробно.
Пусть есть несложная задача: заменить числовые значения от 0 до 20 их строковыми наименованиями. Тут решение напрашивается само собой, и любая проверка условий кажется лишней:
Public Function MyFunction (ByVal Optional iNum As Integer) As String Dim aNameNum() As String aNameNum = Array(“ноль”,“один”,“два”,“три”,“четыре”,“пять”,“шесть”,“семь”,“восемь”,“девять”,“десять”, “одиннадцать”,“двенадцать”,“тринадцать”,“четырнадцать”,“пятнадцать”,“шестнадцать”,“семнадцать”,“восемнадцать”, “девятнадцать”,“двадцать”) MyFunction = aNameNum(iNum) End Function
Однако если переписать эту функцию, используя конструкцию Select Case –
Public Function MyFunction (ByVal Optional iNum As Integer) As String Dim aNameNum() As String Select Case iNum Case 0 MyFunction = “ноль” … … … Case 20 MyFunction = “двадцать” End Select End Function
то в тесте можно обнаружить почти двукратный прирост производительности. В чём же дело? Почему проверка 4‑5 условий быстрее, чем однократное извлечение из массива?
Дело в том, что мы используем интерпретатор, а это значит, что каждая загрузка массива данными – это именно загрузка: до выполнения функции Array он не существует нигде в виде блока данных. А загрузка массива – операция достаточно ресурсоёмкая.
Так что же, такое решение вообще не имеет права на существование? Отнюдь. И оно может даже оказаться наиболее быстрым из всех: ключевое слово здесь – кэш.
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Сделаем следующее: объявим массив aNameNum на уровне модуля как Global, а саму функцию перепишем так, как в Листинге 4. Теперь массив aNameNum будет загружаться данными только однажды – при первом использовании, а при всех последующих вызовах будет применяться уже инициализированный массив. Такая функция будет быстрее, чем функция, использующая сравнение, а уж свою первую инкарнацию она обогнала у меня в 2,2 раза. Результат испытаний можно увидеть на рис. 4. Естественно, такое решение подходит только там, где подобная функция может использоваться многократно.
И наконец
Я обещал вернутся к вопросу о стиле программирования, предусматривающем кодирование путём исключения [Coding by exception], то есть таком, когда добавляется дополнительный код для каждого специального случая.
Безусловно, такой стиль программирования нельзя считать правильным в общем случае – код становится труден для понимания, вероятность ошибки растёт, а рефакторинг, если он потребуется, превращается в кошмар. Но считать антипаттерны недопустимыми вообще тоже было бы большой ошибкой. Мы уже видели, какой прирост по скорости может дать эксплуатация специальных случаев, а иногда это жизненно необходимо.
Поэтому – не пугайтесь нарушать общепринятые нормы, если знаете, что делаете: в конце концов, самый грамотный код – это тот, который работает правильно и быстро.