0

The function looking-at matches a regex, in some cases however I want to match against a literal string. While (looking-at (regexp-quote text)) works, it seems like there might be a way to do this that bypasses regex entirely.

Without this I end up using buffer-substring can comparing the string, but it seems as if there might be a more efficient way to do this as there is some room for error with bounds checking for e.g.

3
  • 1
    There's no obligation to provide such info, but I'm curious, and it just might help with the answers you get (dunno): What's your concern about using regexp-quote to get literal string matching? What's the efficiency concern, e.g., for what kind of use case do you care about this efficiency difference (assuming there is a difference)? Also, do you need looking-at in your use case, or just looking-at-p? Again, just curious - I'd use (looking-at (regexp-quote text)) until/unless in some particular case I found it led to some relevant problem.
    – Drew
    Jul 4, 2023 at 4:01
  • I'm looking to write a package that syntax highlights comments based on their contents, see this post: reddit.com/r/emacs/comments/14pyf8x since this runs as part of font-locking I want it to be as fast as possible, so if there is a quick way to match literal strings, that would be preferable.
    – ideasman42
    Jul 4, 2023 at 6:57
  • So I guess you know the strings you'll encounter ahead of time, so there's no possibility that they contain anything regexp-relevant... I still can't imagine a case where any optimization here is called for - especially seeing the example you show in that linked Reddit post. Remember: font-lock is regexp-based, and lots of font-lock patterns are not regexp-relevant (i.e., plain string matching). And font-lock happens even in situations where speed is important - and it happens repeatedly, all the time. IOW, so far, I can't guess the use case that calls for avoiding regexp-quote here.
    – Drew
    Jul 4, 2023 at 13:48

1 Answer 1

2

You could do something like

(search-forward "string" (+ (point) (length "string")) t)

but I'm not convinced that would be significantly faster than using looking-at-p plus regexp-quote like @Drew suggests.

Here's what some quick benchmarks show for me:

(benchmark-run-compiled 10000000
  (save-excursion
    (search-forward "string" (+ (point) (length "string")) t)))
=> (15.868925050000001 35 8.100802817000044)

(benchmark-run-compiled 10000000
  (save-excursion
    (search-forward "string" (+ (point) 6) t)))
=> (15.703928073000002 35 7.964655790999984)

(benchmark-run-compiled 10000000
  (looking-at-p (regexp-quote "string")))
=> (4.905593267 0 0.0)

(benchmark-run-compiled 10000000
  (looking-at-p "string"))
=> (4.648821162 0 0.0)

(benchmark-run-compiled 10000000
  (looking-at (regexp-quote "string")))
=> (4.6541677340000005 0 0.0)

(benchmark-run-compiled 10000000
  (looking-at "string"))
=> (3.552957473 0 0.0)

so I'd say looking-at or looking-at-p are the functions to use.

5
  • It's highly possible that looking-at-p is slower, because it needs to parse the regexp. search-forward is a more specific function; it knows that its argument is a literal string instead of regexp, which means it gets more information than looking-at-p. When the situation is more specific (more information is known), we can usually choose a better algorithm.
    – shynur
    Jul 4, 2023 at 13:35
  • Anyway, I can't see a reason to use regexp-related functions here.
    – shynur
    Jul 4, 2023 at 13:37
  • 1
    @shynur, I was obliquely asking someone to go and test the actual difference :-)
    – rpluim
    Jul 4, 2023 at 14:25
  • 1
    Note: If the string is long and it doesn't match, then this is NOT performant at all. It systematically runs down the entire string to get its length. Imagine that the first character doesn't match and the string is 4 MB long... Maybe such code makes sense for your (OP's) particular context; dunno. But that would be a corner case, not a general one.
    – Drew
    Jul 4, 2023 at 15:39
  • Sure, in real code you're memoize the length. In any case, quick and dirty benchmarking suggests that looking-at-p beats search-forward here by a factor of 4 at least. I'll update the answer.
    – rpluim
    Jul 4, 2023 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.