9737
@ Подписаться
Сотни бизнес-методик. Тысячи кейсов. Обновления.

сегодня 13885 Подписчиков

Политика конфиденциальности Этот сайт использует cookies, чтобы повысить удобство его использования Вами Понятно

"Медленное быстрее" (иллюстрация описания приёма формализации задачи в программировании)

2014-07-16 15:42:40
Редакция » Всем

Шаблон "Медленное быстрее" (иллюстрация описания приёма формализации задачи в программировании)

(Приведён в качестве примера к данному обсуждению). 

Если задача связана с быстродействием, и Вы имеете противоречие:

  • "Объём данных, которые надо обработать в единицу времени растёт, но быстродействие снижаться не должно"
  • "Данные надо сохранить там (для удобства) и надо сохранить здесь (для быстродействия)"
  • ... и т.д. ... 

попробуйте использовать приёмы "Заранее" и "Наоборот". Ниже приведены примеры.

2014-07-16 15:51:12
Дмитрий Гончаренко » Всем
Пример Дмитрия Гончаренко (www.planfix.ru)

Ситуация: 
 
"Одним из недостатков при использовании онлайн-сервисов является медленное (относительно традиционных локальных приложений) сохранение и обновление информации.
 
Например, когда пользователь пишет комментарий и жмет кнопку "Добавить", происходят следующие операции:
  • сохранение информации на интернет-сервер (зачастую расположенный за тысячи километров);
  • считывание с сервера обновленной страницы, содержащей в том числе и этот комментарий;
  • отрисовка обновленной страницы в браузере пользователя.
Традиционно эта проблема решается сразу по всем фронтам:
  • расширение каналов связи (как пользовательских, так и со стороны сервера);
  • увеличение серверных мощностей (мощный сервер быстрее записывает и считывает информацию);
  • использование специального программного обеспечения на сервере, работающего в памяти и позволяющего избежать "тяжелых" операций записи на диск;
  • улучшения браузера, позволяющие быстрее отрисовывать страницы.
Все это приносит свои плоды, но до скорости работы оффлайн-приложений интернет-сервисам пока еще далеко. При этом использование онлайн-сервисов дает ощутимые преимущества, поэтому пользователи продолжают ими пользоваться, хоть и недовольны скоростью работы".
 
Противоречие:
  • "Данные должны сохраняться на удалённом сервере (чтобы ими можно было  воспользоваться) и 
  • "Данные не должны сохраняться на удалённом сервере (т.к., это долгая операция)
Описание портрета решения: 
  • Было бы идеально, чтобы сохранение данных и их использование не были связаны.
Обостряем/усиливаем (до запредельного состояния):
  • Данные используются до их сохранения
Решение: На первый взгляд кажется, что мешающая часть в данном случае это процесс загрузки и считывания, который занимает время. Избавиться от этого процесса мы не можем, он ключевой.
 
Но, если посмотреть глубже, то видно, что на самом деле пользователю мешает не сам процесс, а вынужденное ожидание его завершения. Вот от этого мешающего свойства "ожидание пользователя" нам и надо избавляться.
 
Это решение используется в некоторых современных интернет-сервисах, например в системе управления задачами Asana (http://asana.com/) - когда пользователь добавляет задачу или комментарий в систему, текст сразу появляется на странице, несмотря на то, что на сервер он еще не попал. 
 
Параллельно запускается невидимый для пользователя процесс записи информации на сервер и получения с сервера обновленного списка задач или комментариев. В это время пользователь может продолжать работать дальше, например добавлять следующий комментарий - для него все выглядит как мгновенная запись данных и готовность системы к работе. 
 
У пользователей такой подход вызывает кучу положительных эмоций, Асану хвалят как самую быструю систему управления задачами - и, хотя она небыстрая, с пользовательской точки зрения это действительно так.
2014-07-16 15:59:20
Сергей В. Сычёв » Всем
Пример Сергея Сычёва (www.triz-ri.ru)

Ситуация: 
 
 
"Выборки из больших баз данных, на самом деле, бывают очень долгими. Например, средней величины супермаркет имеет номенклатуру до 50 000 артикулов, а более крупное предприятие может иметь и сотню тысяч. Сложный запрос, предполагающий и выборку из нескольких таблиц, и вычисления, и вывод данных в определённой форме, и запись отчёта соответственно может выполняться достаточно долго.
 
Понятно, что можно оптимизировать запрос, изменять структуру данных и т.д., можно покупать новые компьютеры, но всё это компромиссные направления - достаточно открыться нескольким новым магазинам в торговой сети и объём данных вырастет скачкообразно".
 
Противоречие: 
  • Надо обработать все данные, чтобы получить верный отчёт
  • Надо обрабатывать не все данные, т.к. это долгая операция
Описание портрета решения: 
  • Было бы идеально, чтобы потребление обработанных не зависело от их получения
Обостряем/усиливаем (до запредельного состояния):
  • Данные потребляются до их получения
Используем [при такой-то формулировке :)] принцип "Наоборот"
 
Варианты:
  • Получаем не всё, а по одной позиции
  • Не ускоряем выборку, а замедляем выборку
Решение: 
  • Отчёт построчно (или уважительными порциями) появляется на «стене» Пользователя и - пока Пользователь его «потребляет» - продолжает выполняться. 
  • Кроме того, запуск «большого отчета» привязали ко времени (по часам компьютера), чтобы Пользователь сам не запускал, а в определенные часы просто подходил к монитору и смотрел как меняются текущие данные. (Похоже на чтение сводок или лент новостей). Пользователь совсем не злится - наоборот. (К тому же, оно всё равно быстрее выползает, чем он это обдумывает)
  • Пользователь, более того, привык к тому, что полный объём данных готов в такое-то время (например в 12-30) и он просто подходит к стене в это время. (Естественно, можно сделать так, чтобы он видел отчёт и утром).
  • Главное у Пользователя не возникает ситуации ожидания, люди их периодически смотрят отчёты как Фейсбук, но не ждут пока что-либо сформируется, и возникает ощущение "офигенной оперативности" :) при относительно медленном выполнении запроса.
Некоторым аналогом являются цитаты в паузах при загрузке нашего сайта (сейчас их уже нет, но раньше, когда Интернет был медленный, они были). Пока шла загрузка страницы, Пользователь читал цитату.
 
2014-07-16 20:36:42
Максим Козельский » Дмитрий Гончаренко

Здравствуйте! Как в Вашем примере обрабатываются ошибки? Например, если данные до сервера не дойдут, то эти данные, появившись было на клиенте, затем исчезнут. Что думать пользователю? Или он получит сообщение: такие-то данные пропали, введите их еще раз?

2014-07-17 18:27:59
Александр Сычёв » Максим Козельский

Уважаемый Максим,

Аналогичную задачу я решал при разработке приложений для операционной системы "Андроид".

Изменения сразу сохраняются на "Клиенте" (быстрая операция), а данные о произошедших, относительно исходного состояния изменениях, складываются в "буфер", содержимое которого затем отправляется на сервер.

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

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

Сервер может не откликнуться в следующих случаях:


1. Соединение не было установлено.
2. Соединение было установлено, но данные не были переданы полностью.
3. Соединение было установлено, данные были переданы и обработаны, но разрыв произошел при передаче ответа.

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


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

С уважением, Александр Сычёв.

2014-07-17 20:34:18
Максим Козельский » Александр Сычёв

Спасибо, Aлександр! Ваше приложение однопользовательское? При многопользовательском режиме во время повторного изменения может обнаружиться, что объект уже заблокирован другим пользователем, после чего его изменение "задним числом" может оказаться недопустимым. Например, другой пользователь перевел объект на статус, на котором нет прав объект изменять ( заказ уже ушел на склад для отгрузки, а менеджер не успел поправить позицию, хотя у него на мониторе все верно).

Не верно ли, что прием "использование данных до их сохранения" применим лишь для однопользовательского режима Или только для чтения данных? При многопользовательском изменении объектов придется ждать ответ сервера оБ успешной блокировке объекта.

2014-07-18 10:04:49
Дмитрий Гончаренко » Максим Козельский

Здравствуйте, Максим!

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

 

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

 

Есть несколько моментов, которые делают описанный подход успешным:

  • Архитектура системы достаточно надежна, на современные коммуникации тоже жаловаться приходиться нечасто, поэтому в 99.9% случаев операция добавления происходит успешно - а значит, пользователю крайне редко приходится сталкиваться с ситуацией, когда его информация не попала на сервер. На мой взгляд, это очень важный момент: если мы уверены в надежности системы и в том, что большая часть операций будет совершена успешно, то лучше отрабатывать редкие нештатные ситуации, чем заставлять пользователя ждать в 100% случаев.
  • За счет того, что соединение с сервером держится постоянно, каждая такая операция занимает секунды - т.е. не очень долго - и информацию о неудавшейся записи пользователь получает очень быстро, не успев выйти за контекст событий (обычно он все еще находится на той же странице). Это облегчает ему повторную отправку в случае случайной неудачи и одновременно предостерегает его от накопления большого количества действий в локальном буфере - психологически некомфортно добавлять записи если видишь, что они не попадают на сервер.
  • При этом данный подход не исключает, что какие-то критические операции (тот же перевод статуса) могут проводиться в традиционном режиме, т.е. пользователь не получит информацию об успешном совершении действия до момента его реального совершения. Это является примером еще одного стандартного (с точки зрения ТРИЗ) подхода - принцип местного качества, когда с разными частями системы мы работаем по-разному.
2014-07-20 14:35:45
Александр Сычёв » Максим Козельский

Уважаемый Максим, 

Моё приложение является многопользовательским, но решение с буфером (в данном частном случае) не создает описываемых проблем. В дополнение к тому, о чём написал Дмитрий Гончаренко, 

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

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

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

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

В таком модельном случае, при частом одновременном резервировании одних и тех же номенклатурных позиций разными многочисленными Пользователями, вполне вероятна ситуация, когда данные "на Клиентах" почти постоянно не будут совпадать с данными на сервере. И - соответственно - очень часто будут отправляться запросы, которые сервер будет отклонять - так, что, в предельном итоге, "никто ничего не допросится", хотя товар на складе есть. И версионность нам тут тоже не поможет, поскольку мы никак не можем иметь несколько версий фактического объема товара на складе.

  

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

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

Спасибо за Ваши вопросы,

Уважаемые Коллеги!

Если Вам нравится наш Форум, Вы можете поддержать его, отправив любую сумму (тогда выберите опцию "Спасибо за Форум").

Вы также можете поддержать конкретное обсуждение и получить гарантированный ответ от наших специалистов (тогда выберите опцию "Прошу эксперта ответить в этой теме").
Задайте Ваш вопрос здесь.

Большое Спасибо!


Яндекс.Метрика