Is there a better (faster) way to step through a variable adding numbers as we go

I have a large selection of data I am copying into a variable. There are multiple numbers within this data that I want to pull out and add together. I wrote the following macro to step through this var line by line, pull out the number if it's in that line and add it to the total. I'll paste a photo of that macro below.

The macro works well and does what I want. The problem is it's slow. When the data is large (as it can be on some days) it can take several seconds for this macro to step through the variable and pull out everything. The can make timing problematic when I want to then call other macros, because I don't know exactly how long it will take.

So... is there any better (ie faster) way to do what I want to do?

Thanks in advance for any suggestions/ideas!

I don't have a good sense of how fast Keyboard Maestro is compared to scripting languages, nor do I know how big your data set is, but I just made a file called investment.txt with 2 million lines, a million lines of

investment1.27 and 5.26 more

and a million blank lines between these. Running a Perl one-liner,

perl -nle 'if(/investment(\d\.\d{1,8})/) {$sum+=$1} END{print $sum;}' investment.txt

on this data set returned the answer (1,270,000) in less than half a second on my M1 MacBook Air. Is this fast enough for what you need?

There's nothing clever here. I just translated your logic to Perl.

1 Like

Wow! I know nothing of Perl so that is like black magic to me. I can kind of read it and figure out what's going on, but I would have no idea how to write that myself. That makes me want to learn some Perl.

At any rate, thank you!

All I did was translate to a different language. Here's how you'd use it in a macro.

Add Investment Amounts.kmmacros (2.3 KB)

Image of macro

As well as @drdrang's excellent suggestion, you can also optimise your current macro. As written you don't do anything with blank lines in the text -- so don't include them in the "For Each". And you're running the regex a second time to get the number -- use a "Try/Catch" to try and extract then add the number, doing nothing on an error (no match). Demo macro:

Search and Add Numbers.kmmacros (5.6 KB)



While speeding up the macro is good, you're not solving your actual problem:

You do know exactly how long it will take -- it takes until it has finished! There's no need to guess about that. If you've got macroB that requires macroA to have completed you could:

  1. Use a "control" macro that fires off macroA then, when macroA has completed, fires off macroB
  2. Add an "asynchronous" action to the end of macroA that fires macroB
  3. Set a global variable at the start of macroA and clear it at the end -- macroB starts with a "Pause until..." action and waits for the global to be cleared

...and there are other methods, like querying KM to see if macroA is running.

Sort out the flow control for your macros and you won't have to worry about unexpected delays breaking the chain.