View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0014957 | MMW v4 | Framework: Scripts/Extensions | public | 2018-07-10 09:14 | 2018-07-18 18:56 |
Reporter | zvezdan | Assigned To | |||
Priority | none | Severity | minor | Reproducibility | sometimes |
Status | feedback | Resolution | open | ||
Platform | Windows | OS | - | OS Version | 10 |
Summary | 0014957: Slow startup because of the MatchCollection object | ||||
Description | Here is the short script that you could use to test the slow down during startup caused by the MatchCollection object, as I described in the related Issue (https://www.ventismedia.com/mantis/view.php?id=14820#c50347). It is executing during startup after which it shows one dialog box telling the running time. After that you could also start it from the Search toolbar by click on the "RegExp Test" button and click on the Test button in the new dialog box. There is also one spin button in that dialog with which you could set the number of iterations for the test - 10000 iterations are running approx. 3 seconds during startup and 2 seconds after that on my computer, but I am not experiencing the problem on my computer, most probably because it is not Win10. However, here is the report about this test script which I got from one user that had the mentioned problem: Load MM 10,000 iterations: 119.94 MM running: 10,000 iterations: 1.17 50,000 iterations: 5.83 100,000 iterations: 11.65 Load MM 5,000 iterations: 49.13 and a second time of 56.76 after running another application MM running: 5,000 iterations: 0.59 10,000 iterations: 1.16 50,000 iterations: 5.81 100,000 iterations: 11.59 As you could see, he is experiencing approx. 100 times slower executing during startup than latter when started from the toolbar for the same number of iterations. As I already explained in the related Issue, this is all happening with Set oMatches = oRegEx.Execute("..."), but only during startup. The same code is running fine latter. I have also attached the packed script as the add-on ready to use. | ||||
Steps To Reproduce | Option Explicit Dim iCount Sub OnStartUp() Dim oMenuItem Set oMenuItem = SDB.UI.AddMenuItem(SDB.UI.Menu_TbSearch, 0, 0) With oMenuItem .Caption = "RegEx Test" .OnClickFunc = "Dialog" .UseScript = Script.ScriptPath End With Set SDB.Objects("RegExTest") = oMenuItem With SDB.IniFile If Len(.StringValue("RegExTest", "Iterations")) = 0 Then .IntValue("RegExTest", "Iterations") = 10000 End If iCount = .IntValue("RegExTest", "Iterations") End With Test End Sub Sub Test() Dim oRegEx Dim oProgress Dim oMatches Dim dtTime Dim i Set oRegEx = New RegExp oRegEx.IgnoreCase = True oRegEx.Global = True oRegEx.Multiline = False Set oProgress = SDB.Progress dtTime = Timer oRegEx.Pattern = "((?:^(?:Preset\d+ *= *)?|, *)ReplaceWith *: *)(\d+|(?:""(?:""""|[^""])*?"")|[^,]+)(?=( *,|$))" For i = 0 To iCount Set oMatches = oRegEx.Execute("Preset230=Menu: ""Partial manipulations"", Name: ""Move right-specified part of <From Field> between (and including) specified strings to <Into Field>..."", Description: ""This preset modifies two fields at once! - - If Assign is on, Opening string is """"("""", Closing string is """")"""", Part number = 2 (counting from the right), Copy opening, Copy closing, Remove opening and Remove closing are on: - The Wall (CD2) (41:55) [1979] (source field) -> The Wall (41:55) [1979] (source field) and (CD2) (destination field) - - If Copy opening and Copy closing are off: - CD2 (destination field) - - If Remove opening and Remove closing are off: - The Wall () (41:55) [1979] (source field) - - If Use RegEx option is on, Opening string is """"[([]"""" and Closing string is """"[)\]]"""", it will be copied parts either between """"("""" and """")"""" or """"["""" and """"]""""."", Shortcut: """", Icon: """", Toolbar: 0, FindWhat: ""<If Caption=""""Assign to destination"""" Value=1 ID=1><If Caption=""""Only if destination is empty"""" Value=0 ID=3>^$<Else>^.*<End If><Else Caption=""""Append to:""""><If Caption=""""Only if destination is not empty"""" Value=0 ID=4><End If><If Caption=""""the start of destination"""" Value=1 ID=2>^<If ID:4>(?!$)<End If><Else Caption=""""the end of destination""""><If ID:4>(?!^)<End If>$<End If><End If>"", FindInto: ""Custom 1"", FindRegExp: 1, WholeWord: 0, ReplaceWith: ""LetVar(0, RegSub(<From Field>, """".*("""" & SetVar(1, <If Caption=""""Use RegEx to specify strings"""" Value=0 ID=5><Else>RegSub(<End If>""""<String Caption=""""Opening string"""" Value=""""("""">""""<If ID:5><Else>, """"[$^*()+[\]\\{}|.?]"""", """"\$$&"""")<End If>) & """")(.*)("""" & SetVar(2, <If ID:5><Else>RegSub(<End If>""""<String Caption=""""Closing string"""" Value="""")"""">""""<If ID:5><Else>, """"[$^*()+[\]\\{}|.?]"""", """"\$$&"""")<End If>) & """")(?:.*?"""" & GetVar(1) & """".*?"""" & GetVar(2) & """"){"""" & <Number Caption=""""Part number"""" Value=""""2"""" MinValue=""""1"""" ID=6> - 1 & """"}.*?$<If Caption=""""Move entire source if it doesn't contain specified strings"""" Value=""""0""""><Else>|.*<End If>"""", """"<If Caption=""""Copy opening string"""" Value=""""1"""">$1<End If>$2<If Caption=""""Copy closing string to destination"""" Value=""""1"""">$3<End If>"""")) & <If ID=1>GetVar(0)<Else><If ID:2>GetVar(0) & <End If>IIf(Len(""""$_"""") > 0 And Len(GetVar(0)) > 0, """"<String Caption=""""Separator"""" Value="""" - """">"""", """""""")<If ID:2><Else> & GetVar(0)<End If><End If> & Execute(""""<If ID:1><If ID:3>If Len(<Into Field>) = 0 Then <End If><Else><If ID:4>If Len(<Into Field>) > 0 Then <End If><End If><If Value=""""bReplacing""""><From Field><Else>sResultFrom<End If> = RegSub(<From Field>, """"""""(.*)("""""""" & GetVar(1) & """""""").*("""""""" & GetVar(2) & """"""""<If Caption=""""Remove opening string"""" Value=1 ID=-7>\s*<End If>)(?=(?:.*?"""""""" & GetVar(1) & """""""".*?"""""""" & GetVar(2) & """"""""){"""" & <ID:6> - 1 & """"}.*?$)"""""""", """"""""$1<If ID:-7><Else>$2<End If><If Caption=""""Remove closing string from source"""" Value=1><Else>$3<End If>"""""""")"""")"", ReplaceFrom: ""Title"", ReplaceRegExp: 0, ReplaceVBScr: 1, MatchCase: 0") If i / 10 = i \10 Then oProgress.Text = i Next SDB.MessageBox FormatNumber(Timer - dtTime, 2) & " sec.", mtInformation, Array(mbOk) End Sub Sub Dialog(oMenuItem) Dim oForm Dim lblTest Dim spnTest Dim btnClose Dim btnTest Set oForm = SDB.UI.NewForm With oForm .Common.SetRect 100, 100, 337, 130 .BorderStyle = 3 .FormPosition = 4 .Caption = oMenuItem.Caption End With Set lblTest = SDB.UI.NewLabel(oForm) With lblTest .Common.SetRect 10, 12, 130, 17 .Caption = "Number of iterations:" End With iCount = SDB.IniFile.IntValue("RegExTest", "Iterations") Set spnTest = SDB.UI.NewSpinEdit(oForm) With spnTest .Common.SetRect 160, 10, 150, 20 .MinValue = -1000000 .MaxValue = 1000000 .Value = iCount End With Script.RegisterEvent spnTest, "OnChange", "spnTest_OnChange" Set btnTest = SDB.UI.NewButton(oForm) With btnTest .Caption = SDB.Localize("&Test") .Common.SetRect 90, 60, 77, 25 End With Script.RegisterEvent btnTest, "OnClick", "btnTest_OnClick" Set btnClose = SDB.UI.NewButton(oForm) With btnClose .Caption = SDB.Localize("&Close") .Common.SetRect 170, 60, 77, 25 .Cancel = True .ModalResult = 2 End With oForm.showModal SDB.IniFile.IntValue("RegExTest", "Iterations") = iCount End Sub Sub spnTest_OnChange(oCtrl) iCount = oCtrl.Value End Sub Sub btnTest_OnClick() Test End Sub | ||||
Additional Information | log: v.4.1.21.1875 - ID: 3E1F | ||||
Tags | No tags attached. | ||||
Attached Files | |||||
Fixed in build | |||||
|
I would like to close this issue since it is not a problem of MediaMonkey. Here is a part of message that I reported to Microsoft at: https://answers.microsoft.com/en-us/protect/forum/protect_defender-protect_scanning-windows_10/last-update-of-windows-defender-causes-terribly/c71cc133-5c5f-447e-95fb-e2641085836d?tm=1527000700529 I made one short VBscript which you could try directly from the command line: '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Option Explicit Const iCount = 10000 Dim oRegEx Dim oMatches Dim dtTime Dim i Set oRegEx = New RegExp oRegEx.IgnoreCase = True oRegEx.Global = True oRegEx.Multiline = False dtTime = Timer oRegEx.Pattern = "((?:^(?:Preset\d+ *= *)?|, *)ReplaceWith *: *)(\d+|(?:""(?:[^""]+|"""")*""))(?=( *,|$))" For i = 0 To iCount Set oMatches = oRegEx.Execute("Preset230=Menu: ""Partial manipulations"", Name: ""Move right-specified part of <From Field> between (and including) specified strings to <Into Field>..."", Description: ""This preset modifies two fields at once! - - If Assign is on, Opening string is """"("""", Closing string is """")"""", Part number = 2 (counting from the right), Copy opening, Copy closing, Remove opening and Remove closing are on: - The Wall (CD2) (41:55) [1979] (source field) -> The Wall (41:55) [1979] (source field) and (CD2) (destination field) - - If Copy opening and Copy closing are off: - CD2 (destination field) - - If Remove opening and Remove closing are off: - The Wall () (41:55) [1979] (source field) - - If Use RegEx option is on, Opening string is """"[([]"""" and Closing string is """"[)\]]"""", it will be copied parts either between """"("""" and """")"""" or """"["""" and """"]""""."", Shortcut: """", Icon: """", Toolbar: 0, FindWhat: ""<If Caption=""""Assign to destination"""" Value=1 ID=1><If Caption=""""Only if destination is empty"""" Value=0 ID=3>^$<Else>^.*<End If><Else Caption=""""Append to:""""><If Caption=""""Only if destination is not empty"""" Value=0 ID=4><End If><If Caption=""""the start of destination"""" Value=1 ID=2>^<If ID:4>(?!$)<End If><Else Caption=""""the end of destination""""><If ID:4>(?!^)<End If>$<End If><End If>"", FindInto: ""Custom 1"", FindRegExp: 1, WholeWord: 0, ReplaceWith: ""LetVar(0, RegSub(<From Field>, """".*("""" & SetVar(1, <If Caption=""""Use RegEx to specify strings"""" Value=0 ID=5><Else>RegSub(<End If>""""<String Caption=""""Opening string"""" Value=""""("""">""""<If ID:5><Else>, """"[$^*()+[\]\\{}|.?]"""", """"\$$&"""")<End If>) & """")(.*)("""" & SetVar(2, <If ID:5><Else>RegSub(<End If>""""<String Caption=""""Closing string"""" Value="""")"""">""""<If ID:5><Else>, """"[$^*()+[\]\\{}|.?]"""", """"\$$&"""")<End If>) & """")(?:.*?"""" & GetVar(1) & """".*?"""" & GetVar(2) & """"){"""" & <Number Caption=""""Part number"""" Value=""""2"""" MinValue=""""1"""" ID=6> - 1 & """"}.*?$<If Caption=""""Move entire source if it doesn't contain specified strings"""" Value=""""0""""><Else>|.*<End If>"""", """"<If Caption=""""Copy opening string"""" Value=""""1"""">$1<End If>$2<If Caption=""""Copy closing string to destination"""" Value=""""1"""">$3<End If>"""")) & <If ID=1>GetVar(0)<Else><If ID:2>GetVar(0) & <End If>IIf(Len(""""$_"""") > 0 And Len(GetVar(0)) > 0, """"<String Caption=""""Separator"""" Value="""" - """">"""", """""""")<If ID:2><Else> & GetVar(0)<End If><End If> & Execute(""""<If ID:1><If ID:3>If Len(<Into Field>) = 0 Then <End If><Else><If ID:4>If Len(<Into Field>) > 0 Then <End If><End If><If Value=""""bReplacing""""><From Field><Else>sResultFrom<End If> = RegSub(<From Field>, """"""""(.*)("""""""" & GetVar(1) & """""""").*("""""""" & GetVar(2) & """"""""<If Caption=""""Remove opening string"""" Value=1 ID=-7>\s*<End If>)(?=(?:.*?"""""""" & GetVar(1) & """""""".*?"""""""" & GetVar(2) & """"""""){"""" & <ID:6> - 1 & """"}.*?$)"""""""", """"""""$1<If ID:-7><Else>$2<End If><If Caption=""""Remove closing string from source"""" Value=1><Else>$3<End If>"""""""")"""")"", ReplaceFrom: ""Title"", ReplaceRegExp: 0, ReplaceVBScr: 1, MatchCase: 0") Next MsgBox FormatNumber(Timer - dtTime, 2) & " sec." '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' I don't have Windows 10, but here are the reports of some users of my add-on that tried this script. The first user reported this: "Using your code with 10,000 iterations the results: 10,000 iterations 11.70 secs 11.41 secs 11.14 secs 11.34 secs Using your code but changing 10,000 iterations to 1,000 iterations 1,000 iterations 1.13 secs 1.15 secs 1.16 secs 1.15 secs NO R-T Protection for 10,000 (10k) iterations is 1.83 and 1.84 secs - I ran 4 times. WITH R-T Protection I get 11.53 and 11.45 secs respectively for same iterations." The same user even tried the same script with the much shorter string for the Execute command, but got just slightly shorter execution: "Test 1 - shorter Execute: 2 tests 9.64 and 9.57 secs respectively." Here is that shorter string: "Preset17=Menu: ""Basic manipulations"", Name: ""Increment Play counter by 1"", Description: """", Shortcut: """", Icon: """", Toolbar: 1, FindWhat: ""^.*"", FindInto: ""Played #"", FindRegExp: 1, WholeWord: 0, ReplaceWith: ""<Into Field> + 1"", ReplaceFrom: ""Track #"", ReplaceRegExp: 0, ReplaceVBScr: 1, MatchCase: 0" The other user reported this: "RegExTest2.vbs time is 40.52 seconds" And the report of the third user: "I don't have an option to turn of the Win Defender Realtime Protection. I guess my Kaspersky Antivirus disabled it. But I tried with and without my antivirus, and it turned out with Kaspersky enabled, the script was running about 39 secs and with Kaspersky disabled it only took 2 seconds to complete. Being curious I tested it on my laptop running Win 10 too but having Avira Antivirus installed. Interestingly it runs even with Avira RT Protection enabled in 1.5 secs! Disabling Avira makes it runs in 1.3 secs. I went further and ran the script on a virtual machine in VirtalBox I'm using now and then. With Windows Defender enabled it took about 16 secs to finish, disabling the Win Defender RT Protection made it finish within 1.6 secs." I don't know what is going on in the background with Kaspersky AV, but I suppose that it has not disabled Windows Defender and because of that it is slow. Maybe it just removed it from the GUI, but I guess that Defender service is still running. |