Unfortunately that eventually does require running the true substring
operation. All of my substrings are short-lived values that are used
immediately, so being lazy doesn't help much. My issue is that Im running
substring several million times to generate very short-lived values that are
almost immediately ready to be collected.
substring/shared does seem to be what I want, although for some reason using
that instead of substring is actually much (~30%) slower. My initial guess as
to why is TR contract boundary shenanigans, although that also seems odd given
that the only contract that should be generated by requiring substring/shared
is string?.
On Fri, Apr 4, 2014 at 4:12 PM, John Clements <[email protected]>
wrote:
> On Apr 3, 2014, at 7:08 PM, Spencer Florence <[email protected]> wrote:
>> Is there any way to perform `substring` without creating a new string? I'm
>> working with lots of very large and (for all intents and purposes) immutable
>> strings and would like to avoid the extra allocations and copy time.
> Seems like it would be fairly easy to roll this yourself:
> #lang racket
> (require rackunit)
> ;; represent a lazy substring operation:
> (struct lazysubstring (str start end))
> ;; force a lazy substring
> (define (lss-force s)
> (substring (lazysubstring-str s)
> (lazysubstring-start s)
> (lazysubstring-end s)))
> ;; get the length of a lazy substring:
> (define (lss-len s)
> (- (lazysubstring-end s) (lazysubstring-start s)))
> ;; create one:
> (define source-text "othho tot stnh ontuh .nt")
> (define lss1 (lazysubstring source-text 3 9))
> (check-equal? (lss-len lss1) 6)
> Obviously, you have to “roll your own” for any operation that you want to
> perform that retains the laziness.
> John
____________________
Racket Users list:
http://lists.racket-lang.org/users