Макрос regexp match ТОРМОЗИТ!
От: WolfHound  
Дата: 19.06.07 14:18
Оценка:
Понадобилось мне тут логи распарсить не тривиальным образом. Те простыми грепами и компанией не обойтись.
Решил использовать немерле.
Ну и макрос regexp match за компанию (нужно же чемто строчки разбирать).
Написал.
Запустил и прослезился.
Она работала очень медленно.
Полез в исходники и не обнаружил там флага RegexOptions.Compiled.
Болие того регексп создается каждый раз перед исполнением.
        // generation of final code for building regular expression and
        // extracting its groups
        <[ 
          def regobj = Regex ($(pat.ToString () : string), 
                              RegexOptions.ExplicitCapture);

          def matchobj = regobj.Match ($val);

          match (matchobj.Success) {
            | true => $(build_checking (alternatives))
            | _ => $defexpr 
          }
        ]>


Замеры показали код с макросом обрабатывает примерно 1-2 метра в секунду.
Без макроса и флага RegexOptions.Compiled 7-8 метров в секунду.
С флагом RegexOptions.Compiled 11-12 метров в секунду.

ИМХО нужно фиксить. Тем болие что тому кто знает компилятор тут похоже на 10 минут работы.
regobj сделать статической да засунуть туда регексп с опциями STRE.RegexOptions.Compiled | STRE.RegexOptions.ExplicitCapture.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Макрос regexp match ТОРМОЗИТ!
От: Иванков Дмитрий Россия  
Дата: 19.06.07 15:31
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>ИМХО нужно фиксить. Тем болие что тому кто знает компилятор тут похоже на 10 минут работы.

WH>regobj сделать статической

А вот это нетривиально, т.к. нету кажется такого понятия как static переменные.
Допустим можно запихнуть в какой-нибудь тип-пустышку, один на все константы или по одному на каждую или еще как.
Но как минимум первая проблема — делать или нет синхронизацию?
Наверное стоит придумать пушку-макрос static


WH> да засунуть туда регексп с опциями STRE.RegexOptions.Compiled | STRE.RegexOptions.ExplicitCapture.


Ну это понятно как, дописать к опциям %| RegexOptions.Compiled.
Можешь замерить скорость?
Re[2]: Макрос regexp match ТОРМОЗИТ!
От: WolfHound  
Дата: 19.06.07 16:13
Оценка: +1
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>А вот это нетривиально, т.к. нету кажется такого понятия как static переменные.

ИД>Допустим можно запихнуть в какой-нибудь тип-пустышку, один на все константы или по одному на каждую или еще как.
Это детали.

ИД>Но как минимум первая проблема — делать или нет синхронизацию?

The Regex class is immutable (read-only) and is inherently thread safe. Regex objects can be created on any thread and shared between threads. For more information, see Thread Safety.

(C)MSDN

ИД>Ну это понятно как, дописать к опциям %| RegexOptions.Compiled.

Если это сделать без staic переменной (те создавать regex каждый раз) это значительно замедлит исполнение (ибо собрать сборку это очень дорого) и приведет к утечкам памяти тк .НЕТ не умеет выгружать код.

ИД>Можешь замерить скорость?

Дык я вроде уже... см первое сообщение.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Макрос regexp match ТОРМОЗИТ!
От: Иванков Дмитрий Россия  
Дата: 19.06.07 16:39
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Иванков Дмитрий, Вы писали:


ИД>>Но как минимум первая проблема — делать или нет синхронизацию?

WH>

WH>The Regex class is immutable (read-only) and is inherently thread safe. Regex objects can be created on any thread and shared between threads. For more information, see Thread Safety.

WH>(C)MSDN

Понятно, я смотрел не в remarks

Thread Safety
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

(C)MSDN

ИД>>Можешь замерить скорость?

WH>Дык я вроде уже... см первое сообщение.
Для полноты картины хотел увидеть скорость макроса с флагом, хотя наверное не изменится от флага скорость.
Re: Макрос regexp match ТОРМОЗИТ!
От: Иванков Дмитрий Россия  
Дата: 19.06.07 20:30
Оценка:
Можно пробовать, патч:

Index: text.n
===================================================================
--- text.n (revision 7710)
+++ text.n (working copy)
@@ -267,12 +267,24 @@
 
         // generation of final code for building regular expression and
         // extracting its groups
+        
+        def ctx = Nemerle.Macros.ImplicitCTX ();
+        def tb = ctx.CurrentTypeBuilder;
+        def static_regobj = Macros.NewSymbol ("static_regobj");
+        def value = Macros.NewSymbol ("value");
+        unless (ctx.InErrorMode) {
+          def tb = tb.DefineNestedType (<[ decl: 
+            private sealed class $(static_regobj : name) {
+              internal static $(value : name) : Regex = 
+                Regex ( $(pat.ToString () : string), RegexOptions.ExplicitCapture %| RegexOptions.Compiled ); 
+            }
+          ]>);
+          tb.Compile ();
+        }
+       
         <[ 
-          def regobj = Regex ($(pat.ToString () : string), 
-                              RegexOptions.ExplicitCapture);
+          def matchobj = $(static_regobj : name).$(value : name).Match ($val);
 
-          def matchobj = regobj.Match ($val);
-
           match (matchobj.Success) {
             | true => $(build_checking (alternatives))
             | _ => $defexpr
Re: Макрос regexp match ТОРМОЗИТ!
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.07 20:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>ИМХО нужно фиксить. Тем болие что тому кто знает компилятор тут похоже на 10 минут работы.

WH>regobj сделать статической да засунуть туда регексп с опциями STRE.RegexOptions.Compiled | STRE.RegexOptions.ExplicitCapture.

Можно конечно подфиксить... создавать для каждого выражения статический регексп и указыват фалг Compiled, но все это полумеры. По уму нужно просто доработать напильником генератор лексеров konsoletyper-а:
Compiler-compiler
Автор: konsoletyper
Дата: 31.03.07

Полуится и вменяемый синтаксис, и скрость ДКА.

Дело в том, что в МС работают (в том числе) очень ленивые программисты (или бездарные). Они, конечно, сделали очень гибкие регекспы, но преобразование в ДКА они не сделели, по этому даже будучи откомпилированными в некоторых случаях их регекспы безбожно тормозят. В сравнении с ними Перловские или даже Яваскриптные регекспы просто летают.

Так что правильным решением было бы просто отакзаться от МС-ных регекспов и заменить их на полноценную реализацию, или что еще лучше, вообще перейти на EBNF и потихоничку приучить к этому все прогрессивное человечество (это я о юзании konsoletyper-овского движка, если кто не понял).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Макрос regexp match ТОРМОЗИТ!
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.07 20:42
Оценка: :)
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Для полноты картины хотел увидеть скорость макроса с флагом, хотя наверное не изменится от флага скорость.


Это если без статика то? Изменится и еще как. Будет еще в 10 раз медленее. Ведь вместо кривой интерпретации будет сначала компиляция, а потом испольнение кривого кода .


ЗЫ

Тут как-то на дотнетном форуме вопрос был. Орлу тоже посоветовали компильнуть регэксп. Они возвращается и заявляет, мол компильнул... стало еще хуже... Потом выяснилось, что он сами объекты динамически создавал.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Макрос regexp match ТОРМОЗИТ!
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.07 20:49
Оценка: 6 (1)
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>+ unless (ctx.InErrorMode) {


Так нельзя. Интеграция работает сразу в ErrorMode, так что ты просто ничего не добавишь. Еще нужно проверять, что ты не под интеграцией. Так что проверяй еще Manager.IsIntelliSenseMode.

И еще не ясно зачем писать "sealed class", если можно просто "module" написать.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Макрос regexp match ТОРМОЗИТ!
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.07 21:37
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Иванков Дмитрий, Вы писали:


ИД>>+ unless (ctx.InErrorMode) {


VD>Так нельзя. Интеграция работает сразу в ErrorMode, так что ты просто ничего не добавишь. Еще нужно проверять, что ты не под интеграцией. Так что проверяй еще Manager.IsIntelliSenseMode.


Кстати, разумно было бы добавить еще одно свойство, что-то вроде IsSafeToAddSideEffect которое було бы тру при InErrorMode == false или при Manager.IsIntelliSenseMode == true. Надо бы в бактрекер записать и добавить.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Макрос regexp match ТОРМОЗИТ!
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 20.06.07 04:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Можно конечно подфиксить... создавать для каждого выражения статический регексп и указыват фалг Compiled, но все это полумеры. По уму нужно просто доработать напильником генератор лексеров konsoletyper-а:

VD>Compiler-compiler
Автор: konsoletyper
Дата: 31.03.07

VD>Полуится и вменяемый синтаксис, и скрость ДКА.

VD>Дело в том, что в МС работают (в том числе) очень ленивые программисты (или бездарные). Они, конечно, сделали очень гибкие регекспы, но преобразование в ДКА они не сделели, по этому даже будучи откомпилированными в некоторых случаях их регекспы безбожно тормозят. В сравнении с ними Перловские или даже Яваскриптные регекспы просто летают.


Не знаю, возможно ли к ДКА прикрутить фичи MS-овских регэкспов. Например, чтобы у меня задать C-подобные комментарии, нужно извратиться. Да и подходит ДКА лучше для разделения на лексемы. А вот как что-то из самой лексемы вычленить, я пока даже не представляю. Я думал об этом, но натыкался на некоторые грабли.

VD>Так что правильным решением было бы просто отакзаться от МС-ных регекспов и заменить их на полноценную реализацию, или что еще лучше, вообще перейти на EBNF и потихоничку приучить к этому все прогрессивное человечество (это я о юзании konsoletyper-овского движка, если кто не понял).


Было бы неплохо. Только кто этим займётся? Я вот пока загружен по полной.
... << RSDN@Home 1.2.0 alpha rev. 672>>
Re[2]: Макрос regexp match ТОРМОЗИТ!
От: WolfHound  
Дата: 20.06.07 08:31
Оценка: -1
Здравствуйте, VladD2, Вы писали:

VD>Можно конечно подфиксить... создавать для каждого выражения статический регексп и указыват фалг Compiled, но все это полумеры. По уму нужно просто доработать напильником генератор лексеров konsoletyper-а:

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

VD>Так что правильным решением было бы просто отакзаться от МС-ных регекспов и заменить их на полноценную реализацию, или что еще лучше, вообще перейти на EBNF и потихоничку приучить к этому все прогрессивное человечество (это я о юзании konsoletyper-овского движка, если кто не понял).

EBNF это конечно хорошо. Но для одноразового кода регехпы лучше ибо писать меньше.
Скажем нужно мне было логи распарсить.
Получилось вот что:
    FileProcessor().
    ProcessLines(inFileName, outFileName, lines => lines.
        MapLazy(line => regexp match (line) {
        | @"[^:]+:(?<time>\d+:\d+:\d).*\]\s*(?<ip>\S+).*" => Some((time, ip))
        | _ => None()
        }).
        FilterOptionalLazy().
        GroupLazy((x, y) => x[0] == y[0]).
        MapLazy(seq => seq.
            CountAllToArray().
            SortInplace((x, y) => y[0] - x[0]).
            MapLazyFiltered
                ( (count, _) => count > 100
                , fun(count, (time, ip)) { $"$time $count $ip" }
                )
        ).
        FlattenLazy()
    );

Но декларативность данного решения меня не устраивает.
Хочется чегото типа такого
    FileProcessor().
    ProcessLines(inFileName, outFileName, StreamFilter {
        RegexFilteredMap(| @"[^:]+:(?<time>\d+:\d+:\d).*\]\s*(?<ip>\S+).*") //{time : string, ip : string}
        Group(time)
        Map(
            Count() //{count : int, value : {time : string, ip : string}}
            Filter(count > 100)
            Sort(-count)
            Map($"$(value.time) $count $(value.ip)")
        )
        Flatten()
    });

А тащить сюда EBNF это просто оверкилл.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
2Константин Л.
От: WolfHound  
Дата: 20.06.07 10:05
Оценка: -1
За минус ответишь?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: 2Константин Л.
От: Alexmoon Украина  
Дата: 20.06.07 10:13
Оценка: -1 :))
Здравствуйте, WolfHound, Вы писали:

WH>За минус ответишь?


ой красиво.
то, что человек выразил несогласие тебе, надеюсь никакой уголовной ответственности не несет. Это не согласие с ним, а лишь не согласие с твоим поведением.
Re: 2Константин Л.
От: Константин Л. Франция  
Дата: 20.06.07 11:52
Оценка: -1
Здравствуйте, WolfHound, Вы писали:

WH>За минус ответишь?


Да. Мне не понравился твой код :


FileProcessor().
    ProcessLines(inFileName, outFileName, lines => lines.
        MapLazy(line => regexp match (line) {
        | @"[^:]+:(?<time>\d+:\d+:\d).*\]\s*(?<ip>\S+).*" => Some((time, ip))
        | _ => None()
        }).
        FilterOptionalLazy().
        GroupLazy((x, y) => x[0] == y[0]).
        MapLazy(seq => seq.
            CountAllToArray().
            SortInplace((x, y) => y[0] - x[0]).
            MapLazyFiltered
                ( (count, _) => count > 100
                , fun(count, (time, ip)) { $"$time $count $ip" }
                )
        ).
        FlattenLazy()
    );


Краткость — сестра таланта, но не в ущерб читабельности:

Если честно, то мне сейчас косяк его разворачивать в нормальный. Пару-тройку def'ов — и он станет лучше.

Конечно же, это все моё личное мнение
Re[2]: 2Константин Л.
От: WolfHound  
Дата: 20.06.07 12:51
Оценка: :)
Здравствуйте, Константин Л., Вы писали:

КЛ>Да. Мне не понравился твой код :

Это одноразовый код. И я об этом написал.
1)Написал.
2)Запустил.
3)Посмотрел что получилось.
4)Если не понял что к чему подкрутил goto 2
5)Забыл.

Ты бы еще результаты grep'ов предложил структуировать.

КЛ>Краткость — сестра таланта, но не в ущерб читабельности:

КЛ>Если честно, то мне сейчас косяк его разворачивать в нормальный. Пару-тройку def'ов — и он станет лучше.
def'ы тут только хуже сделают.

Болие того я и сам сказал что этот вариант мне не нравится.
И как надо я показал.
Идея в том что у нас есть поток данных и мы его преобразуем рядом фильтров.

Наиболие занятные фильтры это:
Group — превращает поток в поток потоков. Группируя элементы с одинаковыми полями указанными в параметрах.
Flatten — превращает поток потоков в поток.

Короче все придельно декларативно.

Нафига тут def'ы не понятно совсем.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Макрос regexp match ТОРМОЗИТ!
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.06.07 13:57
Оценка:
Здравствуйте, konsoletyper, Вы писали:

K>Не знаю, возможно ли к ДКА прикрутить фичи MS-овских регэкспов.


МС, насколько я знраю, просто воспроизвели Перловые регексы. А в Перле они работают очень шустро.

K> Например, чтобы у меня задать C-подобные комментарии, нужно извратиться. Да и подходит ДКА лучше для разделения на лексемы.


А в чем проблема то?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Макрос regexp match ТОРМОЗИТ!
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.06.07 13:57
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>По уму это конечно хорошо.

WH>Но сделать полумеру очень просто и даст заметный результат (на порядок примерно...), а делать по уму... это нужно долго и нудно делать.

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

ЗЫ

Офтоп: Да, там в "Обсуждении статей" есть статья по тестированию С++-компиляторов. Автору нужно помочь с виндовыми компиляторами (ключи и т.п.) глянь, плиз, и кинь писма тем членам команды (С++-никам), которых ты считаешь компетентными в этом вопросе. Помогите автору.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.