Какую самую нелепую пессимизацию вы видели? [закрыто]

Мы все знаем, что преждевременная оптимизация является корнем всего зла, потому что оно приводит к нечитаемому / не поддерживаемому коду. Еще хуже пессимизация, когда кто-то реализует «оптимизацию», потому что он думает , что она будет быстрее, но в итоге она будет медленнее, а также будет глючной, не поддерживаемой и т. Д. Что является самым нелепым примером это то, что вы видели?

146
задан 4 revs, 4 users 100% 3 May 2012 в 14:43
поделиться

36 ответов

На старом проекте мы наследовали некоторых (в других отношениях превосходных) программистов встроенных систем, у которых был серьезный опыт Z-8000.

Наша новая среда была 32-разрядным Sparc Solaris.

Один из парней пошел и изменил весь ints на короткие замыкания для ускорения нашего кода, начиная с захвата 16 битов от RAM было более быстрым, чем захват 32 битов.

Я должен был записать демонстрационную программу, чтобы показать, что захват 32-разрядных значений в 32-разрядной системе был быстрее, чем захват 16-разрядных значений, и объясните, что для захвата 16-разрядного значения ЦП должен был сделать 32-разрядный широкий доступ к памяти и затем кашировать или сместить биты, не нужные для 16-разрядного значения.

81
ответ дан 23 November 2019 в 22:45
поделиться

Мой экс-коллега ( s.o.a.b. , на самом деле), был присвоен для создания нового модуля для нашего Java ERP, который должен был собрать и проанализировать данные клиентов (розничная промышленность). Он решил разделить поле EVERY Calendar/Datetime в его компонентах (секунды, минуты, часы, день, месяц, год, день недели, bimester, триместра (!)), потому что, "как еще я запрошу в течение 'каждого понедельника'?"

5
ответ дан Joril 3 May 2012 в 14:43
поделиться

Я видел, что люди используют alphadrive-7 для общего выведения CHX-LT. Это - нестандартная практика. Более обычная практика должна инициализировать преобразователь ZT так, чтобы bufferication был уменьшен (из-за большего сетевого сопротивления перегрузки), и создайте стиль Java bytegraphications.

Полностью пессимистичный!

58
ответ дан Zalaga 3 May 2012 в 14:43
поделиться

Я однажды видел базу данных MSSQL, которая использовала таблицу 'Root'. Таблица Root имела четыре столбца: GUID (uniqueidentifier), идентификатор (интервал), LastModDate (дата и время) и CreateDate (дата и время). Все таблицы в базе данных были Внешним Key'd к таблице Root. Каждый раз, когда новая строка была создана в любой таблица в дб, необходимо было использовать несколько хранимых процедур для вставки записи в таблицу Root, прежде чем Вы могли добраться до фактической таблицы, о которой Вы заботились о (а не база данных, делающая задание для Вас с несколькими триггерами простые триггеры).

Это создало путаницу подслушавших бесполезных и головные боли, потребовал, чтобы что-либо записанное сверху его использовало sprocs (и устранение моих надежд на представление LINQ к компании. Это было возможно, но просто не стоило головной боли), и завершать его даже не выполняло то, что это, как предполагалось, сделало.

разработчик, который выбрал этот путь, защитил его под предположением, что это сохранило тонны пространства, потому что мы не использовали Гуиды на самих таблицах (но... разве GUID не сгенерирован в таблице Root для каждой строки, которую мы делаем?), улучшенная производительность так или иначе, и сделанный им "легкий" контролировать изменения в базе данных.

, О, и схема базы данных был похож на паука мутанта от ада.

47
ответ дан Dusda 3 May 2012 в 14:43
поделиться

Ничто Важнейшее, я признаю, но я поймал людей использование StringBuffer для конкатенации Строк за пределами цикла в Java. Это было что-то простое как превращение

String msg = "Count = " + count + " of " + total + ".";

в

StringBuffer sb = new StringBuffer("Count = ");
sb.append(count);
sb.append(" of ");
sb.append(total);
sb.append(".");
String msg = sb.toString();

, Это раньше было довольно обычной практикой для использования техники в цикле, потому что это было в известной мере быстрее. Вещь, StringBuffer синхронизируется, таким образом, существует на самом деле дополнительно служебный, если Вы только связываете несколько Строк. (Не говоря уже о том, что различие абсолютно тривиально в этом масштабе.) Две других точки об этой практике:

  1. StringBuilder не синхронизируется, так должен быть предпочтен по StringBuffer в случаях, где Ваш код нельзя назвать от нескольких потоков.
  2. современные компиляторы Java превратят читаемую Конкатенацию строк в оптимизированный байт-код для Вас, когда это будет соответствующим так или иначе.
53
ответ дан 3 revs 3 May 2012 в 14:43
поделиться

Это могло бы быть в более высоком уровне, что, чем Вы были после, но фиксация его (если Вам разрешают) также включает более высокий уровень боли:

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

11
ответ дан Gordon Hartley 3 May 2012 в 14:43
поделиться

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

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

, С другой стороны, наши архитекторы программного обеспечения решили, что распакованные данные должны быть отформатированы в очень читаемый XML-документ и сохранили в нашей базе данных как таковой (в противоположность хранению каждого поля в соответствующем столбце). Их идея состояла в том, что "XML является будущим", "дисковое пространство является дешевым", и "процессор является дешевым", таким образом, не было никакой потребности оптимизировать что-либо. Результат состоял в том, что наши 16-байтовые пакеты были превращены в документы 2 КБ, хранившие в одном столбце, и для даже простых запросов мы должны были загрузить мегабайты XML-документов в памяти! Мы получили более чем 50 пакетов в секунду, таким образом, можно вообразить, как ужасный производительность стала (BTW, компания обанкротилась).

Поэтому снова, нет никакого абсолютного правила. Да, иногда оптимизация слишком рано является ошибкой. Но иногда "пространство/память CPU/диска является дешевым" девизом, реальный корень всего зла.

87
ответ дан MiniQuark 3 May 2012 в 14:43
поделиться

Я когда-то работал над приложением, которое было полно кода как это:

 1 tuple *FindTuple( DataSet *set, int target ) {
 2     tuple *found = null;
 3     tuple *curr = GetFirstTupleOfSet(set);
 4     while (curr) {
 5         if (curr->id == target)
 6             found = curr;
 7         curr = GetNextTuple(curr);
 8     }
 9     return found;
10 }

Просто удаление found, возврат null в конце и изменении шестой строки к:

            return curr;

Удвоенный производительность приложения.

19
ответ дан 3 revs, 2 users 78% 3 May 2012 в 14:43
поделиться

Я думаю, что фраза "преждевременная оптимизация является корнем всего зла", путь, путь по используемому. Для многих проектов это стало оправданием не принять производительность во внимание до поздно в проекте.

Эта фраза часто является опорой для людей для предотвращения работы. Я вижу эту фразу, используемую, когда люди должны действительно сказать "Ну и дела, мы действительно не думали об этом впереди и не имеем времени для контакта с ним теперь".

я видел намного более "смешные" примеры немых проблем производительности, чем примеры проблем, представленных из-за "pessimization"

  • , Читая тот же ключ реестра тысячи (или 10-е тысяч) времен во время запуска программы.
  • Загрузка того же DLL сотни или тысячи времен
  • Пропадающие впустую мега байты памяти путем хранения полных путей в файлы напрасно
  • Не структуры данных организации, таким образом, они поднимают путь больше памяти, чем, им нужно
  • Калибровка всех строк, которые хранят имена файлов или пути к MAX_PATH
  • Бесплатный опрос для вещи, которые имеют события, обратные вызовы или другие механизмы уведомления

, Что я думаю, лучший оператор, это: "оптимизация, не имея размеры и понимая не является оптимизацией вообще - ее справедливое случайное изменение".

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

206
ответ дан 4 revs, 3 users 95% 3 May 2012 в 14:43
поделиться

Базы данных являются pessimization детским парком.

Избранное включайте:

  • Разделение таблица в кратные числа (диапазоном дат, алфавитным диапазоном, и т.д.), потому что это является "слишком большим".
  • Составляют таблицу архива для записей на пенсии, но продолжают к ОБЪЕДИНЕНИЮ его с производственной таблицей.
  • Дублирующиеся все базы данных (подразделением/клиентом/продуктом/и т.д.).
  • Сопротивляются добавляющим столбцам к индексу, потому что он делает его слишком большим.
  • Составляют много сводных таблиц, потому что перевычисление от необработанных данных является слишком медленным.
  • столбцы Create с подполями для оставления свободного места.
  • Денормализовывают в fields-as-an-array.

Это первое, что пришло на ум.

114
ответ дан 2 revs, 2 users 73% 3 May 2012 в 14:43
поделиться

При проверке, прежде чем существует КАЖДАЯ операция JavaScript, действуете ли объект Вы на.

if (myObj) { //or its evil cousin, if (myObj != null) {
    label.text = myObj.value; 
    // we know label exists because it has already been 
    // checked in a big if block somewhere at the top
}

Моя проблема с этим типом кода - никто, кажется, заботится что, если это не существует? Просто ничто? Не давать обратную связь пользователю?

Я соглашаюсь что Object expected ошибки являются раздражающими, но это не лучшее решение для этого.

8
ответ дан 23 November 2019 в 22:45
поделиться

Как насчет экстремизма YAGNI. Это - форма преждевременного pessimization. Это походит каждый раз, когда Вы применяете YAGNI, затем Вы заканчиваете тем, что нуждались в нем, приводя к 10 раз усилию добавить его, чем если бы Вы добавили его в начале. При создании успешной программы затем, разногласия - ВЫ, ИСПЫТЫВАЮТ НЕОБХОДИМОСТЬ в IT. Если Вы привыкли создавать программы, жизнь которых заканчивается, быстро затем продолжают практиковать YAGNI, потому что затем я предполагаю YAGNI.

7
ответ дан 23 November 2019 в 22:45
поделиться

Никакое преступление любому, но я просто градуировал присвоение (Java), который имел это

import java.lang.*;
3
ответ дан 23 November 2019 в 22:45
поделиться

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

8
ответ дан 23 November 2019 в 22:45
поделиться

Я предполагаю, что мог предложить этот драгоценный камень:

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    // Find out how many bytes our value uses
    // so we don't do any uneeded work.
    if (value & 0xffff0000)
    {
        if ((value & 0xff000000) == 0)
            tmp = 3;
        else
            tmp = 4;
    }
    else if (value & 0x0000ff00)
        tmp = 2;

    switch (tmp)
    {
        case 4:
            ISQRT_INNER(15);
            ISQRT_INNER(14);
            ISQRT_INNER(13);
            ISQRT_INNER(12);
        case 3:
            ISQRT_INNER(11);
            ISQRT_INNER(10);
            ISQRT_INNER( 9);
            ISQRT_INNER( 8);
        case 2:
            ISQRT_INNER( 7);
            ISQRT_INNER( 6);
            ISQRT_INNER( 5);
            ISQRT_INNER( 4);
        case 1:
            ISQRT_INNER( 3);
            ISQRT_INNER( 2);
            ISQRT_INNER( 1);
            ISQRT_INNER( 0);
    }
#undef ISQRT_INNER
    return root;
}

Так как квадратный корень был вычислен в очень чувствительном месте, я получил задачу изучения способа сделать его быстрее. Этот маленький рефакторинг уменьшил время выполнения на треть (для комбинации аппаратных средств и используемого компилятора, YMMV):

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1, root = 0;
    #define ISQRT_INNER(shift) \
    { \
        if (value >= (tmp = ((root << 1) + (1 << (shift))) << (shift))) \
        { \
            root += 1 << shift; \
            value -= tmp; \
        } \
    }

    ISQRT_INNER (15);
    ISQRT_INNER (14);
    ISQRT_INNER (13);
    ISQRT_INNER (12);
    ISQRT_INNER (11);
    ISQRT_INNER (10);
    ISQRT_INNER ( 9);
    ISQRT_INNER ( 8);
    ISQRT_INNER ( 7);
    ISQRT_INNER ( 6);
    ISQRT_INNER ( 5);
    ISQRT_INNER ( 4);
    ISQRT_INNER ( 3);
    ISQRT_INNER ( 2);
    ISQRT_INNER ( 1);
    ISQRT_INNER ( 0);

#undef ISQRT_INNER
    return root;
}

Конечно, существуют и быстрее И лучшие способы сделать это, но я думаю, что это - крутой пример pessimization.

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

unsigned long isqrt(unsigned long value)
{
    unsigned long tmp = 1 << 30, root = 0;

    while (tmp != 0)
    {
        if (value >= root + tmp) {
            value -= root + tmp;
            root += tmp << 1;
        }
        root >>= 1;
        tmp >>= 2;
    }

    return root;
}

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

14
ответ дан 23 November 2019 в 22:45
поделиться

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

Вот недавний пример:

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

Я: Почему Вы рассматриваете это? Какова проблема, которую Вы пытаетесь решить?

Его: Таблица X слишком широка, мы делим ее по причинам производительности.

Я: Что заставляет Вас думать, что это слишком широко?

Его: консультант сказал, что это - слишком много столбцов, чтобы иметь в одной таблице.

Я: И это влияет на производительность?

Его: Да, пользователи сообщили о неустойчивом замедлении в модуле XYZ приложения.

Я: Как Вы знаете, что ширина таблицы является источником проблемы?

Его: Это - ключевая таблица, используемая модулем XYZ, и это похоже на 200 столбцов. Это должна быть проблема.

Я (Объясняющий): Но модуль, XYZ в особенности использует большинство столбцов в той таблице и столбцы, которые это использует, непредсказуем, потому что пользователь настраивает приложение для показа данных, которые они хотят отобразить от той таблицы. Вероятно, что 95% времени, мы волновали бы присоединение ко всем таблицам назад вместе так или иначе, которые повредят производительность.

Его: консультант сказал, что это слишком широко, и мы должны изменить его.

Я: Кто этот консультант? Я не знал, что мы наняли консультанта, и при этом они не говорили с группой разработчиков вообще.

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

Я: Ага. Таким образом, консультант, который продает услуги модернизации базы данных, думает, что нам нужна модернизация базы данных....

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

  1. Пропавшие без вести индексов на нескольких столбцах ключа.
  2. Несколько аналитиков данных жулика, которые периодически блокировали ключевые таблицы (включая "также широкую") путем запросов производственной базы данных непосредственно с MSAccess.

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

75
ответ дан 23 November 2019 в 22:45
поделиться

"Независимость базы данных". Это означало не сохраненный procs, триггеры, и т.д. - даже любые внешние ключи.

32
ответ дан 23 November 2019 в 22:45
поделиться

Используя regex для разделения строки, когда простой string.split достаточен

26
ответ дан 23 November 2019 в 22:45
поделиться

Худшим примером, о котором я могу думать, является внутренняя база данных в моей компании, содержащей информацию обо всех сотрудниках. Это получает ночное обновление от HR и имеет веб-сервис ASP.NET на вершине. Много других приложений используют веб-сервис для заполнения вещей как поисковые/выпадающие поля.

Пессимизм - то, что разработчик думал, что повторенные вызовы к веб-сервису будут также не спешить делать повторенные SQL-запросы. Таким образом, что он делал? Приложение запускает чтения события во всей базе данных, и преобразовывает все это в объекты в памяти, сохраненной неограниченно долго, пока пул приложений не переработан. Этот код был настолько медленным, потребуется 15 минут для загрузки меньше чем в 2 000 сотрудников. При непреднамеренной переработке пула приложений в течение дня могло бы потребоваться 30 минут или больше, потому что каждый запрос к веб-сервису запустит несколько параллельных перезагрузок. Поэтому новые наймы не появились бы в базе данных первый день, когда их учетная запись была создана и поэтому не сможет получить доступ к большинству внутренних приложений в их первые дни пары, бездельничая.

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

25
ответ дан 23 November 2019 в 22:45
поделиться

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

Несколько различных раз я обнаружил, что кто-то изготовил вручную bubblesort, потому что ситуация "не потребовала" вызова к "слишком необычный" quicksort алгоритм, который уже существовал. Разработчик был satisified, когда их bubblesort ручной работы работал достаточно хорошо над десятью строками данных, которые они используют для тестирования. Это не перешло вполне также после того, как клиент добавил несколько тысяч строк.

25
ответ дан 23 November 2019 в 22:45
поделиться

Я когда-то должен был попытаться изменить код, который включал эти драгоценные камни в класс Констант

public static String COMMA_DELIMINATOR=",";
public static String COMMA_SPACE_DELIMINATOR=", ";
public static String COLIN_DELIMINATOR=":";

Каждый из них использовался многократно в остальной части приложения в различных целях. COMMA_DELIMINATOR замусорил код более чем 200 использованием в 8 различных пакетах.

20
ответ дан 23 November 2019 в 22:45
поделиться

У меня был коллега, который пытался обмануть оптимизатор нашего компилятора C, и стандартная программа переписала код, который только он мог прочитать. Один из его любимых приемов изменял читаемый метод как (составляющий некоторый код):

int some_method(int input1, int input2) {
    int x;
    if (input1 == -1) {
        return 0;
    }
    if (input1 == input2) {
        return input1;
    }
    ... a long expression here ...
    return x;
}

в это:

int some_method() {
    return (input == -1) ? 0 : (input1 == input2) ? input 1 :
           ... a long expression ...
           ... a long expression ...
           ... a long expression ...
}

Таким образом, первая строка некогда читаемого метода стала бы"return"и вся другая логика была бы заменой по глубоко вложенным terniary выражениям. Когда Вы пытались спорить о том, как это было неудобно в сопровождении, он укажет на то, что вывод блока его метода был тремя или четырьмя инструкциями по сборке короче. Это было не обязательно немного быстрее, но это был всегда крошечный бит короче. Это было встроенной системой, где использование памяти иногда имело значение, но была намного более легкая оптимизация, которая, возможно, была сделана, чем это, которое оставит код читаемым.

Затем после этого по некоторым причинам он решил это ptr->structElement было слишком нечитабельно, таким образом, он начал изменять все их в (*ptr).structElement на теории, что это было более читаемым и быстрее также.

Превращение читаемого кода в нечитабельный код самое большее для 1%-го улучшения и иногда на самом деле более медленный код.

17
ответ дан 23 November 2019 в 22:45
поделиться

Не совсем преждевременная оптимизация - но, безусловно, ошибочная - это было прочитано на сайте BBC из статьи, посвященной обсуждению Windows 7.

Мистер Керран сказал, что команда Microsoft Windows изучала все аспекты операционной системы, чтобы внести улучшения. «Мы смогли сократить время выключения на 400 миллисекунд, слегка подрезав музыку выключения WAV-файла.

Я еще не пробовал Windows 7, поэтому могу ошибаться, но готов поспорить, что Есть и другие проблемы, которые важнее, чем время, необходимое для выключения. В конце концов, когда я вижу сообщение «Завершение работы Windows», монитор выключается, и я ухожу - как эти 400 миллисекунд помочь мне?

6
ответ дан 23 November 2019 в 22:45
поделиться

Очень поздно в этой теме я знаю, но я видел это недавно:

bool isFinished = GetIsFinished();

switch (isFinished)
{
    case true:
        DoFinish();
        break;

    case false:
        DoNextStep();
        break;

    default:
        DoNextStep();
}

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

26
ответ дан 23 November 2019 в 22:45
поделиться

Самый большой номер один, с которым я снова и снова сталкиваюсь в собственном программном обеспечении:

Не использовать функции СУБД по причинам «переносимости», потому что «мы могли бы захотеть переключиться к другому продавцу позже ».

Прочтите мои губы. Для любых внутренних работ: ЭТО НЕ БУДЕТ!

19
ответ дан 23 November 2019 в 22:45
поделиться
var stringBuilder = new StringBuilder();
stringBuilder.Append(myObj.a + myObj.b + myObj.c + myObj.d);
string cat = stringBuilder.ToString();

Лучшее использование StringBuilder, которое я когда-либо видел.

31
ответ дан 23 November 2019 в 22:45
поделиться

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

"Эта часть не должна быть быстрой" (архивирующие журналы) "Этой частью должна быть Хелла быстро" (принятие новых соединений)

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

Просто ответив на простой вопрос "Я получаю что-нибудь от наличия этой части кода очень быстро?" будет большая инструкция. Я имею в виду, использование здравого смысла оптимизирует другие части проекта!

3
ответ дан 23 November 2019 в 22:45
поделиться

Один коллега должен был проверить доступ к странице для определенной роли - "Администратор" только. Это - то, что она записала:

.

if( CurrentUser.CurrentRole == "Role1" || CurrentUser.CurrentRole == "Role2")  
{
// Access denied
} 
else
{
// Access granted
}

вместо

if( !CurrentUser.CurrentRole.equals("Admin") ) 
{
 // access denied
}  

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


Тот же коллега был также соединениями для производства и архивной таблицей для всех запросов.

2
ответ дан 23 November 2019 в 22:45
поделиться

Другой необычный прием производительности :)

if (!loadFromDb().isEmpty) {
    resultList = loadFromDb();
    // do something with results
}

За маленькую цену дополнительного хита DB Вы экономите все то время, делая как 10 строк кода, которые, вероятно, не сделали бы многого в пустом списке так или иначе. И вещи как это были рассеяны на всем протяжении кода :)

2
ответ дан 23 November 2019 в 22:45
поделиться

Я собирался упомянуть, что StringBuilder для tiny/non-looping представляют в виде строки concats, но его упомянутый.

Помещение переменных метода в частных участников класса для препятствования им то, чтобы быть " собранным "мусор" каждый раз выполнения метода". Переменные являются типами значения.

1
ответ дан 23 November 2019 в 22:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: