4

I'm currently working on creating a tiny expression language in Apex. I'm following https://craftinginterpreters.com which develops a simple lexer / parser in Java. I'm working on the lexer now which traverses the source character by character. Apex does not have a native character type. I'm wondering if it would be better to go to the work of treating characters as Integers.

Integer c = 'Hello, world!'.charAt(currentPosition);

or

String c = 'Hello, world!'.substring(currentPosition, currentPosition + 1);

CPU time is a consideration as it might have to parse 1,000's of small source expressions in a regular transaction. I suspect the low friction path is to implement characters as strings of length 1.

I thought someone here is been down this path and would have some advice or a pointer or two.

Thanks, Peter

1 Answer 1

5

I compared both of those methods to another method you may have overlooked: getChars. I got the following times in MS for each (lower is better):

Method Time
charAt 2512
substring 3338
getChars 744

I tested each against a String consisting of 100,000 characters for dramatic effect (and to get more accurate measurements). All three methods were called in the same transaction to avoid variances caused by server load between transactions.

If you don't mind working with Unicode codes instead of strings, you can get up to a 400% increase in performance by converting the string to Integer values via getChars, but it will cost 4 bytes per "character" for heap usage, which is 4 times as much as it costs as a String. Overall, if you can spare the heap usage, the CPU tradeoff is definitely worth it.

4
  • This is exactly what I looking for! Thank you so much! You're right I had missed getChars(). My plan then is going to be to convert the source string into an array of Integer at the start. Have a combination of constants and helper functions to map integers to supported symbols, letters and numbers digits. Finally convert identifiers back into strings using. fromCharArray(). Definitely a good apex learning experience.
    – muchavie
    Commented Jan 11, 2022 at 16:08
  • sfdcfox, if you're watching this thread there is the final result of the lexer / parser I wrote. Final result was that the parser was too slow to use in production. (Performance of the lever to good thanks to your help! github.com/pogilvie/RecordFilter
    – muchavie
    Commented May 30, 2022 at 0:06
  • @muchavie That's pretty cool. This is fully installable in a Scratch Org, yes? I'll do some research and maybe I can get you a PR sometime this week. It looks too good to let it go to waste.
    – sfdcfox
    Commented May 30, 2022 at 0:52
  • Yes it installs in a scratch org. I've enjoyed the project greatly. It has general utility even in its current form. It just didn't work out for the application I had in mind which was a pre filter for the Trigger Actions Framework.(github.com/mitchspano/apex-trigger-actions-framework). Hope you have fun and I'm happy to take a PR!
    – muchavie
    Commented May 31, 2022 at 1:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .