• Save
Rubylight Pattern-Matching Solutions
Upcoming SlideShare
Loading in...5
×
 

Rubylight Pattern-Matching Solutions

on

  • 2,627 views

 

Statistics

Views

Total Views
2,627
Views on SlideShare
446
Embed Views
2,181

Actions

Likes
0
Downloads
0
Comments
0

5 Embeds 2,181

http://jug.lv 2175
http://translate.googleusercontent.com 2
http://assets.txmblr.com 2
https://www.google.lv 1
https://www.google.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Rubylight Pattern-Matching Solutions Rubylight Pattern-Matching Solutions Presentation Transcript

  • 1Rubylight programmingcontest 1 resultsjug@rubylight.com
  • Входящие сообщения- 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 photode profil?- Привет! У нас сегодня акция. Заходи,сюда узнаешь больше!
  • Шаблоны (patterns)- IPhone- youtube.com/watch- look here- Заходи, сюда- photo
  • Проверка по шаблонам- 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 photode profil?- Привет! У нас сегодня акция. Заходи,сюда узнаешь больше!
  • Интерфейсpublic interface IPatternMatcher {void addPattern(String pattern);String checkText(String text);}
  • Дополнительно- Оценивается производительностьрешения!- Подробности на сайтах JUG.LV иhttps://wiki.rubylight.com/display/JUG- Решения ждем до 31 Мая 2013- Интересные реализации будутрассмотрены и отмечены на следующемсобрании JUG
  • Зачем это надо- Борьба со спамом в Ask.fm- Анти-вирусные приложения- Network intrusion detectionsystems(NIDS)- Поиск геномов в ДНК- grep/fgrep утилита в Unix
  • Простое решение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;}
  • Поиск одного шаблонаI like IPhones!IPhoneIPhoneIPhoneIPhoneIPhoneIPhoneIPhoneIPhone
  • `СложностьO(m*p) — в худшем случаеO(m*n) — в лучшем случаеm — длина текстаn — количество шаблоновp — суммарная длина всех шаблонов
  • Загруженность CPU- 1000 сообщений в секунду- 35 000 шаблонов
  • Что делать?- Добавлять сервера- Оптимизировать алгоритм
  • Наше решение- Строим хеш таблицу для шаблонов- Сканируем входной текст по 3 символа- Вычисляем хеш из этих 3 символов- Ищем шаблон по хешу
  • Хеш функцияyoutube – hash(you) -> 676phone – hash(pho) -> 4277photo – hash(pho) -> 4277look here – hash(loo) -> 64718
  • Хеш таблица0...676......4277......64718...65536nullyoutubephoto phonelook herenullnullnullnull
  • Поиск шаблонаI like phones!I l – hash-> 10234li – hash-> 676 - youtubelik – hash-> 64718ike – hash-> 676Ke – hash-> 52546E p – hash-> 3682ph – hash-> 32568pho – hash-> 4277 - photo, phone
  • Хеш функцияpublic int calculateHash(String text, int startIndex) {return (text.charAt(startIndex)*11 +(text.charAt(startIndex + 1) * 13) +(text.charAt(startIndex + 2) * 29))% entryArray.length;}
  • Распределение
  • Хеш функция IIint calculateHash(String text, int startIndex) {return((text.charAt(startIndex)<<8)*111 +(text.charAt(startIndex + 1) * 91) +(text.charAt(startIndex + 2)<<4) * 113)% entryArray.length;}
  • Распределение II
  • Загруженность CPU после- 1000 сообщений в секунду- 35 000 шаблонов
  • Решение не оптимально- Только 3 первых символа учитываются- Можно использовать Rolling hash- Возможны низкоуровневые оптимизации
  • Оптимальное решение- Сначала достигаем оптимальнойсложности O()- Потом делаем низкоуровневыеоптимизации
  • Присланные решения- Всего было прислано 17 решений- Участвовало 10 разработчиков- 3 решения не прошли тест- 1 решение выполнялось слишком долго- До финала дошло 6 решений- Все, кроме одного — самописные- Коментарии в коде отсутствуют
  • Тест производительности- 25 000 шаблонов- 1000 000 входящих текстовых сообщений- Сообщения от 3 до 300 любых символов- Шаблоны от 3 до 300 любых символов- Ограничение по памяти 512Mb- Предварительный разогрев- Все взято из реальной системы
  • Финальныйзапуск
  • Лучшее решение- Trie структура данных (индекс шаблонов)- Низкоуровневая оптимизация- Оптимизирован поиск потомков- Оптимизирована работа с текстом
  • TrieP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Trie - поиск шаблонаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)MY IPHONE
  • Поиск потомкаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)
  • Поиск потомкаP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)H P T....min: H max: T0 1 8 12....
  • Поиск потомкаl p yo hhon tne o......otubeoketcmin: l max: ymin: n max: trootmin: n max: t
  • Обход текста (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];}}
  • Обход текста (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...}
  • Что можно улучшить?- Может занимать много памяти- Поиск подстроки всегда начинается скорня
  • НаукаMichael Oser Rabin Richard Manning KarpAlfred Aho
  • Существующие алгоритмы- Aho-Corasick string matching algorithm (1975)- Rabin-Karp string search algorithm (1987)- Commentz-Walter algorithm
  • Алгоритм Aho-CorasickP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)
  • Алгоритм Aho-CorasickP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)
  • Алгоритм Aho-CorasickP HHOTOOST(PHOTO)(HOST)NE(PHONE)TIP(TIP)
  • 5Поздравляем победителей!https://wiki.rubylight.com/display/JUGjug@rubylight.com
  • Все решения1 708ms Aivars Kalvans, Trie с оптимизациями3 205ms Arkadi Shishlov, Aho-Corasick библиотека6 356ms Eugene Igans, RadixTrie12 140ms Reinis Reinikovs, Trie + TreeMap для потомков19 353ms Kiril Menshikov, Trie +?56 220ms Deniss Mosičkins, Rolling hash
  • 5Rubylight programmingcontest 2jug@rubylight.com
  • Исходные данные●Highload project, запросы обрабатываютсясотнями серверов●Сервера (инстанции) находятся в облакеAmazon●Плата берется за каждый час работы каждогоинстанса●Мы можем програмно стартовать иостанавливать инстансы●Нагрузка в течении дня меняется
  • ЗадачаОбработать как можно большезапросов в течении всеговремени теста, затративминимальное количество денегна оплату инстанций
  • Изменение нагрузки
  • Подсчет прибыли●Чем больше мы обрабатываем запросов, тембольше наша прибыль!●Каждый инстанс может обработать не болеемиллиона запросов в час●Каждый обработаный запрос приносит доход.●Расходы на оплату инстансов вычитаются изприбыли●За недостаточную для текущей нагрузкимощность взимается штраф
  • При недостаточноймощности●Если текущая мощность (количествоинстанций) недостаточна для текущейнагрузки, количество обработанныхзапросов ограниченно количествоминстанцийй●Кроме этого, взимается штраф,пропорциональный квадрату от разницымежду текущей мощностью и требуемойдля данной нагрузки
  • Имплементацияinterface InstanceManager {void loadNotification(long requestCount, CloudAPI cloudApi);}interface CloudAPI {void startInstances(int n);void stopInstances(int n);}●Implement InstanceManager●InstanceManager.loadNotification будетвызываться каждый час в симуляторе сколичеством запросов, поступивших запоследний час
  • Ограничения●Java 7 (other JVM languages are not allowed)●Open-source Java libraries available in publicMaven repositories●Pure Java - No native code●No filesystem and network access●Single threaded●-Xmx512m
  • Подсчет результата●Тест прогоняется “в течении месяца”●Результат = R – I – F●R – количество обработанных запросов * настоимость запроса●I – сумма расходов на инстанции●F – сумма штрафов
  • Дополнительно●Подробности на сайтах JUG.LV иhttps://wiki.rubylight.com/display/JUG●Решения ждем до 31 Июня 2013●Интересные реализации будутрассмотрены и отмечены наследующем собрании JUG
  • 6Ждем ваших решений!Удачи!https://wiki.rubylight.com/display/JUGjug@rubylight.com