(require srfi/13 srfi/14)
(define (valid-dna? seq)
(string-every (char-set #\A #\C #\G #\T) seq))
Do I need to manually extract (char-set #\A #\C #\G #\T)
to a separate definition as following version. Or the compiler/optimizer will recognize it as a constant and do it for me? Are there any performance difference between the two? (require srfi/13 srfi/14)
(define (valid-dna? seq)
(define nucleotides (char-set #\A #\C #\G #\T))
(string-every nucleotides seq))
You think that the second version is better (in terms of efficiency) somehow? Why?
If valid-dna?
is called multiple times, I thought (char-set #\A #\C #\G #\T)
would be evaluate multiple times. The second one may only evaluate once at read/compile time because it’s a constant definition.
Several things: 1. If you intend to avoid evaluating (char-set #\A #\C #\G #\T)
multiple times when valid-dna?
is invoked multiple times, then you need to lift it outside of valid-dna?
. Your second code still has (char-set #\A #\C #\G #\T)
inside the function, so it won’t make a difference.
- Donald Knuth said “premature optimization is the root of all evil”. Judging that
(char-set #\A #\C #\G #\T)
is a constant time operation, whether you lift it or not probably won’t make a difference. Before doing any optimization, you should benchmark it first to see where the bottleneck is. Optimizing wrong spots won’t make your program faster.
Like this? (require srfi/13 srfi/14)
(define nucleotides (char-set #\A #\C #\G #\T))
(define (valid-dna? seq)
(string-every nucleotides seq))
Yes
If you want to do that for the sake of readability, go for it. If you want to do it to optimize the function, no, it won’t make your program faster.
I’m not trying to optimize a program. I just trying to avoid redundant computation.
That’s exactly what optimization is…
Alternative: (define valid-dna?
(let ([nucleotides (char-set #\A #\C #\G #\T)])
(λ (seq)
(string-every nucleotides seq))))
I thought it should be done at compile time. (char-set #\A #\C #\G #\T)
should be a constant no matter where i put it.
I don’t know where you get the idea about “done at compile-time”, but it’s wrong. char-set
is a function. It needs to be run at run-time.
Optimizer might be able to partially evaluate your program at compile-time, but that’s not guaranteed.
@wanpeebaw a literal will be evaluated at compile time, e.g.: (define (valid-dna? seq)
(for/and ([ c (in-string seq) ])
(member c '(#\A #\C #\G #\T))))