12

Racket で大きな csv ファイルから日付を解析しようとしています。

これを行う最も簡単な方法は、新しいdate構造体を作成することです。week-dayただし、パラメータとパラメータが必要year-dayです。もちろん、私はこれらを持っていません。これはdate、私が理解していないモジュールの本当の弱点のようです。

そのため、代わりにfind-seconds、生の日付値を秒に変換し、それを に渡すことにしましたseconds->date。これは機能しますが、非常に遅いです。

(time
 (let loop ([n 10000])
   (apply find-seconds '(0 0 12 1 1 2012)) ; this takes 3 seconds for 10000
   ;(date 0 0 12 1 1 2012 0 0 #f 0) ; this is instant
   (if (zero? n)
       'done
       (loop (sub1 n)))))

find-seconds10000 の値を処理するのに 3 秒かかり、数百万あります。もちろん、構造体の作成はdate瞬時に行われますが、曜日、年の値はありません。

私の質問は次のとおりです。

1.)日付構造体の作成にweek-day/が必要なのはなぜですか?year-day

2.)find-secondsこれほど遅いはずですか (つまり、バグですか)? それとも私は何か間違ったことをしていますか?

3.) 日付を高速に解析する代替手段はありますか。関数があることは知っsrfi/19ていstring->dateますが、ラケットの組み込み構造体ではなく、そのモジュールの構造体を使用するようにすべてを変更する必要があります。また、find-seconds の同じパフォーマンス ヒットが発生する可能性がありますが、わかりません。

4

2 に答える 2

7

そのように文書化されていませんが、と で構造体を使用する場合、week-dayyear-dayは「ノーオペレーション」であるように見えます。両方を 0 に設定すると、aは文句を言いません。それらを無視していると思われます:datedate->secondsdate->seconds

#lang racket

(require racket/date)

(define d (date 1    ;sc
                2    ;mn
                3    ;hr
                20   ;day
                8    ;month
                2012 ;year
                0    ;weekday  <<<
                0    ;year-day <<<
                #f   ;dst?
                0    ;time-zone-offset
                ))

(displayln (seconds->date (date->seconds d)))

;; =>
#(struct:date* 1 2 3 20 8 2012 1 232 #t -14400 0 EDT)
                               ^ ^^^

私の推測では、構造体は、 whereおよびdateで使用するために定義されており、興味深い情報を提供することになるでしょう。次に、 では、これらのフィールドが欠落している別の構造体を定義するのではなく (日付を決定するために「冗長」であるため、当然のことながらイライラします:)) で使用するために、同じ構造体が再利用されました。seconds->dateweek-dayyear-daydate->secondsdate->seconds

それは役に立ちますか?あなたの質問からは、CSV からの日付情報を使用して何をしようとしているのか明確ではありません。整数値に変換したい場合はseconds、上記がうまくいくはずです。他に何か思い当たることがあれば、説明できるかもしれません。

于 2012-08-21T01:09:16.920 に答える
3

これは の見落としだと思いracket/dateます。

の呼び出しfind-secondsは、秒数を見つけるために検索する必要があるため、コストがかかります。また、曜日を知る必要があるだけなので、不要な計算です。

アドバイスを得るために、メーリングリストに書き込みます。

于 2012-08-19T11:42:45.077 に答える