2. Входящие сообщения
- What type of iPhone do you have?
- Hi, take a look here:
http://www.youtube.com/watch?
v=RC_6skf1-t
- Salut est-ce que tu peux aimer ma photo
de profil?
- Привет! У нас сегодня акция. Заходи,
сюда узнаешь больше!
4. Проверка по шаблонам
- What type of iPhone do you have?
- Hi, take a look here:
http://www.youtube.com/watch?
v=RC_6skf1-t
- Salut est-ce que tu peux aimer ma photo
de profil?
- Привет! У нас сегодня акция. Заходи,
сюда узнаешь больше!
6. Дополнительно
- Оценивается производительность
решения!
- Подробности на сайтах JUG.LV и
https://wiki.rubylight.com/display/JUG
- Решения ждем до 31 Мая 2013
- Интересные реализации будут
рассмотрены и отмечены на следующем
собрании JUG
7. Зачем это надо
- Борьба со спамом в Ask.fm
- Анти-вирусные приложения
- Network intrusion detection
systems(NIDS)
- Поиск геномов в ДНК
- grep/fgrep утилита в Unix
8. Простое решение
public void addPattern(String pattern) {
patternList.add(pattern);
}
public String checkText(String text) {
for(String pattern : patternList) {
if(text.contains(pattern)) {
return pattern;
}
}
return null;
}
9. Поиск одного шаблона
I like IPhones!
IPhone
IPhone
IPhone
IPhone
IPhone
IPhone
IPhone
IPhone
10. `
Сложность
O(m*p) — в худшем случае
O(m*n) — в лучшем случае
m — длина текста
n — количество шаблонов
p — суммарная длина всех шаблонов
16. Поиск шаблона
I like phones!
I l – hash-> 10234
li – hash-> 676 - youtube
lik – hash-> 64718
ike – hash-> 676
Ke – hash-> 52546
E p – hash-> 3682
ph – hash-> 32568
pho – hash-> 4277 - photo, phone
17. Хеш функция
public int calculateHash(String text, int startIndex) {
return (text.charAt(startIndex)*11 +
(text.charAt(startIndex + 1) * 13) +
(text.charAt(startIndex + 2) * 29))
% entryArray.length;
}
24. Присланные решения
- Всего было прислано 17 решений
- Участвовало 10 разработчиков
- 3 решения не прошли тест
- 1 решение выполнялось слишком долго
- До финала дошло 6 решений
- Все, кроме одного — самописные
- Коментарии в коде отсутствуют
25. Тест производительности
- 25 000 шаблонов
- 1000 000 входящих текстовых сообщений
- Сообщения от 3 до 300 любых символов
- Шаблоны от 3 до 300 любых символов
- Ограничение по памяти 512Mb
- Предварительный разогрев
- Все взято из реальной системы
27. Лучшее решение
- Trie структура данных (индекс шаблонов)
- Низкоуровневая оптимизация
- Оптимизирован поиск потомков
- Оптимизирована работа с текстом
41. Поиск потомка
l p y
o hh
o
n tn
e o
..
....
o
t
u
b
e
o
k
etc
min: l max: y
min: n max: t
root
min: n max: t
42. Обход текста (String)
public final class String {
private final char value[];
private final int offset;
private final int count;
public char charAt(int index) {
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
}
43. Обход текста (reflection)
public PatternMatcher() {
valueField_ = String.class.getDeclaredField("value");
offsetField = String.class.getDeclaredField("offset");
valueField_.setAccessible(true);
offsetField.setAccessible(true);
}
public String checkText(String text) {
chars = (char [])valueField_.get(text);
offset = offsetField.getInt(text);
// work with chars[] and offset
...
}
44. Что можно улучшить?
- Может занимать много памяти
- Поиск подстроки всегда начинается с
корня
53. Исходные данные
●
Highload project, запросы обрабатываются
сотнями серверов
●
Сервера (инстанции) находятся в облаке
Amazon
●
Плата берется за каждый час работы каждого
инстанса
●
Мы можем програмно стартовать и
останавливать инстансы
●
Нагрузка в течении дня меняется
54. Задача
Обработать как можно больше
запросов в течении всего
времени теста, затратив
минимальное количество денег
на оплату инстанций
56. Подсчет прибыли
●
Чем больше мы обрабатываем запросов, тем
больше наша прибыль!
●
Каждый инстанс может обработать не более
миллиона запросов в час
●
Каждый обработаный запрос приносит доход.
●
Расходы на оплату инстансов вычитаются из
прибыли
●
За недостаточную для текущей нагрузки
мощность взимается штраф
57. При недостаточной
мощности
●
Если текущая мощность (количество
инстанций) недостаточна для текущей
нагрузки, количество обработанных
запросов ограниченно количеством
инстанцийй
●
Кроме этого, взимается штраф,
пропорциональный квадрату от разницы
между текущей мощностью и требуемой
для данной нагрузки
58. Имплементация
interface InstanceManager {
void loadNotification(long requestCount, CloudAPI cloudApi);
}
interface CloudAPI {
void startInstances(int n);
void stopInstances(int n);
}
●
Implement InstanceManager
●
InstanceManager.loadNotification будет
вызываться каждый час в симуляторе с
количеством запросов, поступивших за
последний час
59. Ограничения
●
Java 7 (other JVM languages are not allowed)
●
Open-source Java libraries available in public
Maven repositories
●
Pure Java - No native code
●
No filesystem and network access
●
Single threaded
●
-Xmx512m
60. Подсчет результата
●
Тест прогоняется “в течении месяца”
●
Результат = R – I – F
●
R – количество обработанных запросов * на
стоимость запроса
●
I – сумма расходов на инстанции
●
F – сумма штрафов
61. Дополнительно
●
Подробности на сайтах JUG.LV и
https://wiki.rubylight.com/display/JUG
●
Решения ждем до 31 Июня 2013
●
Интересные реализации будут
рассмотрены и отмечены на
следующем собрании JUG