HaskellのReadPを使用して、ファイル内の数字のリストに対して非常に単純なパーサーを行いました。それは動作しますが、非常に遅いです...このタイプのパーサーのこの通常の動作ですか、何か間違っていますか?HaskellのReadPの使用方法を修正しました。
答えて
import Text.ParserCombinators.ReadP
import qualified Data.IntSet as IntSet
import Data.Char
setsReader :: ReadP [ IntSet.IntSet ]
setsReader =
setReader `sepBy` (char '\n')
innocentWhitespace :: ReadP()
innocentWhitespace =
skipMany $ (char ' ') <++ (char '\t')
setReader :: ReadP IntSet.IntSet
setReader = do
innocentWhitespace
int_list <- integerReader `sepBy1` innocentWhitespace
innocentWhitespace
return $ IntSet.fromList int_list
integerReader :: ReadP Int
integerReader = do
digits <- many1 $ satisfy isDigit
return $ read digits
readClusters:: String -> IO [ IntSet.IntSet ]
readClusters filename = do
whole_file <- readFile filename
return $ (fst . last) $ readP_to_S setsReader whole_file
setReader
が数字の間の空白は、任意できるようにされているので、指数関数的挙動を有します。ラインのよう:
12 34 56
これらのパースを見ている:あなたは、これは長い行のために手に負えなくなる可能性がどのように見ることができました
[1,2,3,4,5,6]
[12,3,4,5,6]
[1,2,34,5,6]
[12,34,5,6]
[1,2,3,4,56]
[12,3,4,56]
[1,2,34,56]
[12,34,56]
。 ReadP
は、すべての長さの順に有効なパーズを返します。最後のパーズに到達するには、これらすべての中間パースを通過しなければなりません。変更:
int_list <- integerReader `sepBy1` innocentWhitespace
へ:
int_list <- integerReader `sepBy1` mandatoryWhitespace
mandatoryWhitespace
のに適した定義については、この指数関数的な振る舞いをスカッシュします。 parsecで使用される解析手法は、この種のエラーに対してより寛容です。これは、欲張りなので、特定のブランチで入力を消費すると、そのブランチにコミットされ、戻ってくることはありません(明示的に要求しない限り)。したがって、それが正しく12
を解析すると、それは解析されることはありません1 2
。もちろん、それはあなたの選択肢をどのような順序で述べるかが重要であることを意味します。私はいつも考えるべき痛みが少しあります。
また、私は使用します。
head [ x | (x,"") <- readP_to_S setsReader whole_file ]
を有効な全ファイルの解析を抽出するには、場合、それは非常に迅速にすべての入力を消費するが、その入力を解釈する百bazillionの方法がありました。あいまいさに気にしない場合は、最初のものが早く到着するため、最初のものを最後のものよりもむしろ返すでしょう。
今すぐご利用ください!ありがとう! – dsign
- 1. ベストプラクティス:フライウェイ・マイグレーション・スクリプトを使用した後の修正方法
- 2. ASP.Net MVCでAutoMapperを使用する方法を修正しました
- 3. CygwinでHaskellコードをコンパイルし、Windows上のHaskellプラットフォームの他のバグを修正しました。
- 4. .NET用ライブラリを修正しました
- 5. 「System.AggregateExceptionがmscorlib.dllで発生しました」の修正方法
- 6. ワークステーションがクラッシュしました - SVNを修正する方法
- 7. RazorとMVC3を使用してwebgridのページャーメソッドのCSSを修正しました
- 8. ジャパンマッパーを使用するための依存関係を修正しました
- 9. ApacheでURLの%のエスケープを正しく修正しました
- 10. スクリプトを使用したElasticsearch multitypesクエリの不具合の修正
- 11. StAXを使用してXML文書を少し修正しました
- 12. XSLを使用してXMLの小さな部分を修正する方法
- 13. jQuery Mobileの固定フッターを修正する方法は? jQueryMobileを使用して
- 14. Cでの単体テストを使用した修正
- 15. StackOverflowエラーを修正しました
- 16. ヘルプメモリリークを修正しました
- 17. Rails 3ルーティングエラーを修正しました。
- 18. Haskellでコマンドライン引数を使って関数を修正するためのディスパッチ
- 19. Haskell正規表現ライブラリを使用した置換/置換
- 20. Matlabで修正された配列を使用したプロット。
- 21. ng-storageを使用してng-clickを完了したときにボタンの色を修正する方法は?
- 22. アンドロイドプロジェクトの修正方法
- 23. メモリリークの修正方法は?
- 24. オーバーラップの修正方法は?
- 25. スクリプトの修正方法は?
- 26. DynamicJasper:java.lang.NoSuchMethodErrorエラーの修正方法
- 27. HaskellでのParallel Strategiesの使用方法
- 28. 修正方法:java.lang.NoClassDefFoundError:org.slf4j.LoggerFactory
- 29. scapy:スニッフィングされたトラフィックのTTLを修正する正しい方法
- 30. キーを変更した後にデータを修正する方法
入力ファイルの大きさはどれくらいですか?私は病理学的に遅いものは見つけられませんが、setReaderに中間リストを使用させたくないかもしれませんし、入力のStringではなくByteStringのほうが良いかもしれません。また、Text.Read.LexモジュールにReadP整数パーサーのreadIntPがあります。これは、integerReaderよりもパフォーマンスが向上する可能性があります。 –
ヘルプスティーブンに感謝します。 ReadPを使ったのは初めてのことですが、私はText.Read.Lexについて知りませんでした。 – dsign