KnowBrainer Speech Recognition
Decrease font size
Increase font size
Topic Title: Why is my DNS Advanced Script running so slow?
Topic Summary: My script runs slow after I use it for a while. Is something wrong with it?
Created On: 09/14/2020 09:02 PM
Status: Post and Reply
Linear : Threading : Single : Branch
 Why is my DNS Advanced Script running so slow?   - wristofdoom - 09/14/2020 09:02 PM  
 Why is my DNS Advanced Script running so slow?   - Lunis Orcutt - 09/14/2020 10:11 PM  
 Why is my DNS Advanced Script running so slow?   - Edgar - 09/15/2020 11:57 AM  
 Why is my DNS Advanced Script running so slow?   - wristofdoom - 09/23/2020 11:47 AM  
 Why is my DNS Advanced Script running so slow?   - Edgar - 09/23/2020 03:23 PM  
 Why is my DNS Advanced Script running so slow?   - Matt_Chambers - 09/15/2020 01:04 PM  
 Why is my DNS Advanced Script running so slow?   - Edgar - 09/15/2020 03:13 PM  
 Why is my DNS Advanced Script running so slow?   - Matt_Chambers - 09/15/2020 04:04 PM  
 Why is my DNS Advanced Script running so slow?   - Edgar - 09/16/2020 09:59 AM  
 Why is my DNS Advanced Script running so slow?   - Edgar - 09/15/2020 03:15 PM  
 Why is my DNS Advanced Script running so slow?   - Ag - 09/15/2020 03:48 PM  
Keyword
 09/14/2020 09:02 PM
User is offline View Users Profile Print this message

Author Icon
wristofdoom
Power Member

Posts: 58
Joined: 09/03/2020

Hi, I have an Advanced Script command that I use heavily for a screenwriting project that I'm working on. During a writing session, it works fine for a while, but sometimes after a while (seems like 30 or 40 minutes) the script starts executing painfully slow.

 

The desired behavior for the script is that it formats some text, then types the text, and then send some linebreaks to prep me for the next block of text. But when this issue occurs, the text gets sent very slowly, with a lot of delay between each individual character that gets type it out.

 

For example, if I say the command "new character John", then the desired behavior is to basically hit enter twice (two new line breaks), send the @ symbol, type the name of the character (in this case John), and then hit enter once.

 

When this issue occurs, it takes 10 seconds for all of these steps to finish completing.

 

My computer is fast and new. It's resources are not being taxed when this is happening (my CPU usage stays below 15%, and my memory usage stays below 65%, while this issue is happening.

 

The command name is called "new <tag> <dictation>"

 

The "<tag>" list is a list of options that will send some extra text if needed. So for example, if I say "new voiceover John", then the desired output is "@JOHN (V.O.)" surrounded by linebreaks. If I just say "new character John", then no extra "tag" is typed after the name.

 

The exact code is below.

 

Sub Main

   SendKeys "{Enter 2}", 1 

   SendKeys "@", 1

   SendKeys UCase (ListVar2), 1

       If ListVar1 = "Voice over" Then SendKeys " {(}V.O.{)}", 1

       If ListVar1 = "Off screen" Then SendKeys " {(}O.S.{)}", 1

       If ListVar1 = "Radio" Then SendKeys " {(}RADIO{)}", 1

       If ListVar1 = "Phone" Then SendKeys " {(}PHONE{)}", 1

       If ListVar1 = "Screen" Then SendKeys " {(}SCREEN{)}", 1

       If ListVar1 = "Pre lap" Then SendKeys " {(}PRE-LAP{)}", 1

       If ListVar1 = "Post lap" Then SendKeys " {(}POST-LAP{)}", 1

   SendKeys "{Enter}", 1

End Sub

 

Any help is appreciated. I have to quit the document and then reopen it to fix the issue. Very annoying.



-------------------------

Dragon Professional Individual v15.6. Windows 10. Knowbrainer 2017.

 09/14/2020 10:11 PM
User is offline View Users Profile Print this message

Author Icon
Lunis Orcutt
Top-Tier Member

Posts: 38006
Joined: 10/01/2006

Are you using Ver. 15.6? The new scripting engine is much faster. Your script looks fine but if the problem continues, you might consider converting it to a DVC script or just copy your existing script into KnowBrainer which never slows down; except the 1st time you deploy your command. Dragon's new WinWrap Basic scripting engine is a major improvement but the developers haven't tied down the loose ends and that's why KnowBrainer still works better and never slows down. We've noticed a lot of our Dragon Advanced-Scripting command slowing down after about 20 minutes or so.



-------------------------

Forum Mission Statement
Trial Downloads
Dragon/Sales@KnowBrainer.com 
(615) 884-4558 ext 1

 09/15/2020 11:57 AM
User is offline View Users Profile Print this message

Author Icon
Edgar
Top-Tier Member

Posts: 915
Joined: 04/03/2009

Originally posted by: wristofdoom  

 

The exact code is below.   

Sub Main

   SendKeys "{Enter 2}", 1 

   SendKeys "@", 1

   SendKeys UCase (ListVar2), 1

       If ListVar1 = "Voice over" Then SendKeys " {(}V.O.{)}", 1

       If ListVar1 = "Off screen" Then SendKeys " {(}O.S.{)}", 1

       If ListVar1 = "Radio" Then SendKeys " {(}RADIO{)}", 1

       If ListVar1 = "Phone" Then SendKeys " {(}PHONE{)}", 1

       If ListVar1 = "Screen" Then SendKeys " {(}SCREEN{)}", 1

       If ListVar1 = "Pre lap" Then SendKeys " {(}PRE-LAP{)}", 1

       If ListVar1 = "Post lap" Then SendKeys " {(}POST-LAP{)}", 1

   SendKeys "{Enter}", 1

End Sub

 

This slowdown is a common experience with Dragon. As a temporary workaround you might try using the Dictation Box; if your script is "application-specific" or "window-specific" change it to "global". With your mouse cursor in the place where you want the new text to appear say "show dictation box" (the Dictation Box should open). Now, utter the phrase to trigger your command; the text should appear in the dictation box quickly. Finally, say "click transfer" (or maybe just "transfer" depending on your Option setting for "require click…"); the text should be transferred quickly.

If this works without slowdowns (try it for a while - as you noticed it might take 20+ minutes before the slowdowns become noticeable) you can use it as a permanent workaround or you could get one of the other commercial dictation transfer boxes offered here on the forum.

Another option would be to use AutoIT3, AutoHotKeys (both free and Basic-based) to build compiled scripts which you would then trigger with Dragon/KnowBrainer. If you are a programmer you could do the same with a C++/C# application.

Aside - I think in another thread you asked about improving your scripts…

   Select Case ListVar1

      Case "Off screen"

         SendKeys " {(}O.S.{)}", 1

      Case "Radio"

         SendKeys " {(}RADIO{)}", 1

      [… The other cases would go here]

      Case Else

         TTSPlayString "did not recognize the dictation"

         Wait 3

         Exit All

   End Select

Replace those "If" statements with this "Select" construction. Unless you change the "If" statements into "If… ElseIf… [Else…] End If" your script will evaluate each "If" statement even after it has found a match - probably trivial in this case but good practice.



-------------------------

-Edgar
DPI 15.3, 64-bit Windows 10 Pro, OpenOffice & Office 365, Norton Security, Shure X2U XLR to USB mic adapter with Audio Technica DB135 vocal mic, Asus X299-Deluxe Prime, Intel Core i9-7940X (14 core, 4.3 GHz overclocked to 4.9 GHz), G.SKILL TridentZ Series 64GB (4 x 16GB) DDR4 3333 (PC4 26600) F4-3333C16Q-64GTZ, NVIDIA GIGABYTE GeForce GTX 1060 GV-N1060G1 GAMING-6GD REV 2.0 6GB graphics card with 3 1920x1080 monitors

 09/23/2020 11:47 AM
User is offline View Users Profile Print this message

Author Icon
wristofdoom
Power Member

Posts: 58
Joined: 09/03/2020

Hello, I have updated my script to use cases rather than "if" statements, as you advised.

 

I've got it working except for one part of it.

 

Command name: add <tag> <dictation>

 

Sub Main
   SendKeys "^%+{3}", 1                'set Microsoft Word "character" style
   SendKeys "@", 1                     'prefix the character's name
   SendKeys UCase (ListVar2), 1        'character's name in all caps
   Select Case ListVar1                'check the cases
      Case "Voice over", "VO"
         SendKeys " {(}V.O.{)}", 1
      Case "Off screen", "OS"
         SendKeys " {(}O.S.{)}", 1
      Case "Radio"
         SendKeys " {(}RADIO{)}", 1
      Case "Phone"
         SendKeys " {(}PHONE{)}", 1
      Case "Screen"
         SendKeys " {(}SCREEN{)}", 1
      Case "Pre lap"
         SendKeys " {(}PRE-LAP{)}", 1
      Case "Post lap"
         SendKeys " {(}POST-LAP{)}", 1
      Case Else                 
        Wait .1
        Exit All
   End Select
   SendKeys "{Enter}"
   SendKeys "^%+{5}", 1                'set Microsoft Word "dialogue" style
   If ListVar1 = "Wryly" Then SendSystemKeys "{Ctrl+NumKey4}"     'This will not execute currently
   If ListVar1 = "Wryly" Then SendKeys "{(}"                      'This will not execute currently
End Sub

 

 

I added these extra commands at the very end that only kick in if ListVar1 aka  == "Wryly". This is a different sort of case than the other ones, because a "wryly" element appears on a separate line and opens a new parentheses without filling in any text. The user (me) will then fill in the rest of the text includes the parentheses.

 

This code makes sense to me, but not to my computer: when I dictate a command like "add wryly Edgar" I expect to get this:

 

@EDGAR
(

 

instead, I am getting just this:


@EDGAR

 

 

There is no line break at the end. So basically everything after the "end select" line does not execute if I use the "wryly" keyword for ListVar1.

 

Does every reference to ListVar1 need to be inside the SELECT CASE/END SELECT section?

 

I thought about adding a case for "wryly" within the select section, but then I would have to redundantly add...

 

   SendKeys "{Enter}"
   SendKeys "^%+{5}", 1   
...to every single case that is not "wryly", which would be repetitive and verbose.

Any advice on the most elegant way to handle this?

 

Thanks



-------------------------

Dragon Professional Individual v15.6. Windows 10. Knowbrainer 2017.



 09/23/2020 03:23 PM
User is offline View Users Profile Print this message

Author Icon
Edgar
Top-Tier Member

Posts: 915
Joined: 04/03/2009

Okay, the problem is that you have a "Else" case statement which includes "Exit All". Since you do not handle the "Wryly" case it falls into the "Else" and the program exits without falling out of the "Select" statement. You can add a [Case "Wryly"] which does nothing:
Case "Wryly"
Else
   ' I tend to put an error message here
   'MsgBox "there was a problem…"
   Exit All

 



-------------------------

-Edgar
DPI 15.3, 64-bit Windows 10 Pro, OpenOffice & Office 365, Norton Security, Shure X2U XLR to USB mic adapter with Audio Technica DB135 vocal mic, Asus X299-Deluxe Prime, Intel Core i9-7940X (14 core, 4.3 GHz overclocked to 4.9 GHz), G.SKILL TridentZ Series 64GB (4 x 16GB) DDR4 3333 (PC4 26600) F4-3333C16Q-64GTZ, NVIDIA GIGABYTE GeForce GTX 1060 GV-N1060G1 GAMING-6GD REV 2.0 6GB graphics card with 3 1920x1080 monitors

 09/15/2020 01:04 PM
User is offline View Users Profile Print this message

Author Icon
Matt_Chambers
Top-Tier Member

Posts: 257
Joined: 08/09/2018

In 15.6, this runs quickly for me:

Option Explicit
Dim x As String
Dim y As Variant

Sub Main
x=ListVar1
y=ListVar2
If InStr(y,"\") Then y = Left(y,InStr(y,"\")-1)
SendKeys "~~",1
SendKeys x & "@",1
SendKeys y
SendKeys "~"
End Sub

Listvar1 is just the list of names.
Listvar2 has these entries:
{(}O.S.{)}\off screen
{(}PHONE{)}\phone
{(}POST-LAP{)}\post lap
{(}PRE-LAP{)}\pre-lap
{(}RADIO{)}\radio
{(}SCREEN{)}\screen
{(}V.O.{)}\ voice over



 09/15/2020 03:13 PM
User is offline View Users Profile Print this message

Author Icon
Edgar
Top-Tier Member

Posts: 915
Joined: 04/03/2009

Matt's option looks very good conceptually but needs to be modified slightly for the fact that ListVar1 is the tag from a list and ListVar2 is an open dictation (for the name). Also the line which builds the performer's name starts with the @ so should read
SendKeys "@" & UCase(ListVar2), 1
I don't think there is any practical reason to dimension a Variant variable; I'm pretty sure that List Variables are always guaranteed to be strings - the only time either of the List Variables are manipulated the return values are also guaranteed to be strings. ListVar2 is only manipulated once so it makes no sense to store it and manipulate the stored value. The fact that ListVar1 is manipulated and accessed multiple times makes it reasonable to dimension it as a string and use the variable after assignment.

-------------------------

-Edgar
DPI 15.3, 64-bit Windows 10 Pro, OpenOffice & Office 365, Norton Security, Shure X2U XLR to USB mic adapter with Audio Technica DB135 vocal mic, Asus X299-Deluxe Prime, Intel Core i9-7940X (14 core, 4.3 GHz overclocked to 4.9 GHz), G.SKILL TridentZ Series 64GB (4 x 16GB) DDR4 3333 (PC4 26600) F4-3333C16Q-64GTZ, NVIDIA GIGABYTE GeForce GTX 1060 GV-N1060G1 GAMING-6GD REV 2.0 6GB graphics card with 3 1920x1080 monitors

 09/15/2020 04:04 PM
User is offline View Users Profile Print this message

Author Icon
Matt_Chambers
Top-Tier Member

Posts: 257
Joined: 08/09/2018

Originally posted by: Edgar Matt's option looks very good conceptually but needs to be modified slightly for the fact that ListVar1 is the tag from a list and ListVar2 is an open dictation (for the name). Also the line which builds the performer's name starts with the @ so should read SendKeys "@" & UCase(ListVar2), 1 I don't think there is any practical reason to dimension a Variant variable; I'm pretty sure that List Variables are always guaranteed to be strings - the only time either of the List Variables are manipulated the return values are also guaranteed to be strings. ListVar2 is only manipulated once so it makes no sense to store it and manipulate the stored value. The fact that ListVar1 is manipulated and accessed multiple times makes it reasonable to dimension it as a string and use the variable after assignment.

Good catch on the open dictation. I missed that.

The only reason I dimensioned ListVar1 as a variant was that I got an error message when I did it as a string. Not sure why it's working now as a string, when it wasn't before.

Which raises the question, why does DPI 15.6 start all commands with Option Explicit?

 09/16/2020 09:59 AM
User is offline View Users Profile Print this message

Author Icon
Edgar
Top-Tier Member

Posts: 915
Joined: 04/03/2009

Originally posted by: Matt_ChambersThe only reason I dimensioned ListVar1 as a variant was that I got an error message when I did it as a string. Not sure why it's working now as a string, when it wasn't before. Which raises the question, why does DPI 15.6 start all commands with Option Explicit?

I'm used to Basic-like languages for which "Option Explicit" is "always on" and does not need to be stated explicitly. When I first started scripting with Dragon I tried to get out of the habit of dimensioning my variables but have now reverted.

As to why - having it on catches typos. It might also force the programmer to think about type conversion.



-------------------------

-Edgar
DPI 15.3, 64-bit Windows 10 Pro, OpenOffice & Office 365, Norton Security, Shure X2U XLR to USB mic adapter with Audio Technica DB135 vocal mic, Asus X299-Deluxe Prime, Intel Core i9-7940X (14 core, 4.3 GHz overclocked to 4.9 GHz), G.SKILL TridentZ Series 64GB (4 x 16GB) DDR4 3333 (PC4 26600) F4-3333C16Q-64GTZ, NVIDIA GIGABYTE GeForce GTX 1060 GV-N1060G1 GAMING-6GD REV 2.0 6GB graphics card with 3 1920x1080 monitors

 09/15/2020 03:15 PM
User is offline View Users Profile Print this message

Author Icon
Edgar
Top-Tier Member

Posts: 915
Joined: 04/03/2009

Also, Matt's code is more easily extensible - all you need to do is add tags to the list with no change to the underlying script. Well done Matt!

-------------------------

-Edgar
DPI 15.3, 64-bit Windows 10 Pro, OpenOffice & Office 365, Norton Security, Shure X2U XLR to USB mic adapter with Audio Technica DB135 vocal mic, Asus X299-Deluxe Prime, Intel Core i9-7940X (14 core, 4.3 GHz overclocked to 4.9 GHz), G.SKILL TridentZ Series 64GB (4 x 16GB) DDR4 3333 (PC4 26600) F4-3333C16Q-64GTZ, NVIDIA GIGABYTE GeForce GTX 1060 GV-N1060G1 GAMING-6GD REV 2.0 6GB graphics card with 3 1920x1080 monitors

 09/15/2020 03:48 PM
User is offline View Users Profile Print this message

Author Icon
Ag
Top-Tier Member

Posts: 449
Joined: 07/08/2019

I was going to suggest that in AHK, Python, or C# one would use an associative array, a hash, to map the command strings to the SendKey strings => time complexity O(length of string[s]). Rather than thecascaded IF statements, which have

(I'm not sure if Advanced Scripting or DVC have associative arrays.)

Matt's code moves that operation into Dragon's recognition and grammar list parsing, which one might hope uses hashes -- although I suspect it actually uses a probability weighted tree/graph traversal, possibly a digit tree (trie). (I hope that Dragomn does not do a linear list match, although sometimes I wonder, when it is particularly slow.) Nevertheless, it is probably negligible additional work on top of what Dragon is already doing for you, at least so long as you do not have thousands or millions of combinations via your lists. Which you don't.

I.e. Matt is probably right.

Moreover, to gain the benefit of a hash or tree data structure you need to amortize the cost of building the hash over many uses of the command. Dragon does this naturally. If you interpret your code from scratch each time, that won't be happening. If your code is compiled, then a good compiler may have prepoulated your associative array, so you only pay the cost to read it in from memory - and not even that on a decent OS. Lacking that, if the data structure & command can persist across several invocations... I know how to do that in AHK, it's fundamental to sharing state between the autoexecute section and dynamic threads - but it does not happen for free if you just ShellExecute a .AHK script each time. Oveerall, for a constant, not-changing associative array, a compiler is probably the best option. C#, AHK, Python all have compilers, and/or interpreters that do caching. Again, I do not know if Advanced Scripting or DVC or Knowbrainer do any of that. I thought that might be why KnowBrainer is so slow after saving a command, but Lunis says that KnowBrainer does not compile, only interprets. Although there is a big space in between.

--

As for why your code gets slower, all I can imagine is a memory leak.



-------------------------

DPG15.6 (also DPI 15.3) + KB, Sennheiser MB Pro 1 UC ML, BTD 800 dongle, Windows 10 Pro, MS Surface Book 3, Intel Core i7-1065G7 CPU @ 1.3/1.5GHz (4 cores, 8 logical, GPU=NVIDIA Quadro RTX 3000 with Max-Q Design.

Statistics
31794 users are registered to the KnowBrainer Speech Recognition forum.
There are currently 0 users logged in.
The most users ever online was 12124 on 09/09/2020 at 04:59 AM.
There are currently 593 guests browsing this forum, which makes a total of 593 users using this forum.

FuseTalk Standard Edition v4.0 - © 1999-2020 FuseTalk™ Inc. All rights reserved.