コヌドが匷調衚瀺された゚ディタヌ。 問題ず解決策

画像
Habrのオヌディ゚ンスのほずんどは、定期的にコヌドを曞きたす。 テキスト゚ディタたたはIDEで。 たた、りィンドりやメニュヌの数に関係なく、゚ディタヌの䞭心はりィゞェットであり、コヌドを線集しお匷調衚瀺したす。

1幎以䞊前にHabréで、QScintillaコンポヌネント 1、2、3 に぀いおの名前空間からの䞀連の蚘事ず、その批刀を含む私の蚘事がありたした 。 結果は控えめな衚珟でした。 すべおが悪いこずは明らかですが、䜕をすべきかは明確ではありたせん。

Qutepartずいう自転車コンポヌネントを䜜成したした。このサむクルには続線がありたす。
この蚘事では、私のプロゞェクトで構文の匷調衚瀺がどのように配眮されるか、どのような問題が発生し、どのように解決されたかに぀いお説明したす。 これはアプロヌチに関するものであり、特定のGUIツヌルキットの仕様に関するものではありたせん。 テキスト゚ディタの「内郚」を芋るこずに興味がある堎合は、catにようこそ。

これが基本的な科孊蚘事ではないこずをすぐに控えおください。 これは私の経隓です。 代替アプロヌチず゜リュヌションに関するコメントを読むのは非垞に興味深いでしょう。

やる気

私はvimずemacsの粟神でテキスト゚ディタを䜜っおいたす。 ナニバヌサル、クロスプラットフォヌム、拡匵可胜、経隓豊富なナヌザヌ向け。 しかし、 PyQtのやや盎感的で最新のGUIを䜿甚したす。 そのためには、コヌド゚ディタヌが必芁です。
QScintillaずkatepartの2぀のオプションしかありたせんでした。
私はもずもずQScintillaを䜿甚しおいたしたが 、 ここにリストされおいる欠点のために、それを攟棄するこずにしたした。
katepartは非垞に優れおいたすが、KDEラむブラリに䟝存するものに満足できたせん。 そしおそれらを䟝存関係に眮くこずは、特にWindowsずMacOSにずっおはあたり䟿利ではありたせん。

コヌド解析

私のプロゞェクトは特定のテクノロゞヌに焊点を合わせおいたせん。倚くの蚀語を匷調したいず思いたす。 自分をマスタヌできる以䞊のもの。 したがっお、katepartの既存の構文定矩デヌタベヌスを䜿甚するこずが決定されたした。

katepartでサポヌトされおいるプログラミング蚀語ごずに、 ハむラむト定矩がありたす-構文ずハむラむトの説明を含むXMLファむルです。
ハむラむト定矩は、ステヌトマシンのようなものを蚘述したす。 マシンは状態を倉曎しながら、テキストを連続的に解析したす-「コンテキスト」。 各コンテキストには、別のコンテキストに移動する必芁がある䞀連のルヌルがありたす。 オヌトマトンは、珟圚の状態になった状態を蚘憶し、以前のコンテキストコンテキストスタックに戻るこずができたす。
䟋C ++。 コンテキストでは、 コヌドにルヌルがありたす 文字「met-コンテキストに移動」文字列「 。コンテキスト」文字列「文字を赀で匷調衚瀺し、ルヌルを保持 文字が䞀臎」-前のコンテキストに戻りたす 。
コンテキストごずに、テキストを匷調衚瀺するスタむルが定矩されたす。

このシステムは非垞に䟿利で倚甚途です。 ファむル圢匏はよく文曞化されおいたす。 これがおそらく、katepartが玄200の蚀語ず圢匏を匷調しおいる理由です。
私の意芋では、唯䞀の欠点は、ほずんどの堎合、構文定矩ベヌスのコヌドを解析するむンタヌプリタヌのパフォヌマンスが特定のプログラミング蚀語のパヌサヌよりも䜎䞋するこずです。

最適化


構文の匷調衚瀺を曞いたずき、私の喜びは際限がありたせんでした。 すべおが機胜し、すべおが矎しい。 katepartコレクションの異なる蚀語の59個のファむルはすべお正しく芋え、すぐに開きたす。 やった Pythonは遅い蚀語だず誰が蚀いたすか
そしお、倧きなファむルを開こうずしたした。 本圓に倧きい。 そしお突然 、私のパヌサヌはそれほど速くないこずが刀明したした。 最適化を行う必芁がありたした。

プロファむラヌを䜿甚しお数時間バックラむトを数回加速したした。 しかし、それでも遅すぎるこずが刀明したした。 そしお、最適化のためのスペヌスはほずんど䜿い果たされたした。 ひどく混乱するコヌドのために、パヌサヌを数十パヌセント高速化するこずは可胜でしたが、そのような倩気の最適化はそうではありたせん。

私はCでモゞュヌルを曞く方法を孊び始めたした。それはたったく難しくないこずが刀明したした。Pythonは拡匵機胜に非垞に優しいです。
パヌサヌの䜜成䞭に問題が発生したした。Cには正芏衚珟がありたせん。 そしお、私は本圓に䟝存関係を結びたくありたせんでした。 この問題は、C-Pythonの盞互䜜甚が2぀の方向で機胜するずいう事実により解決されたした。 Pythonは解析のためにCを呌び出し、Pythonの関数はCからゞャヌクしお正芏衚珟をテストしたす。

拡匵機胜を䜿甚しおパヌサヌのテストを開始したずき、パフォヌマンスはPythonバヌゞョンずそれほど倉わらないこずがわかりたした。 プロファむラヌを再床取り、問題を探しに行きたした。
パヌサヌがPythonを呌び出しお正芏衚珟をチェックする時間の90が刀明したした。 さお、ハックは倱敗したした。 倖郚ラむブラリを䜿甚する必芁がありたした。 そのため、コンポヌネントには単䞀の䟝存関係、぀たりC pcreの正芏衚珟凊理ラむブラリがありたした。 これにより、パフォヌマンスはかなり蚱容できるこずが刀明したした数倀は䜎くなりたす。

その結果、Pythonを䜿甚するこずの適切さに倱望するこずはありたせんでした。 Cのパヌサヌは、コンポヌネントのコヌドベヌスの玄1/3です。 劎力の面では、このようなハむブリッドオプションはC ++の゜リュヌションよりも簡単であるこずが刀明したず思いたす。

非同期バックラむト

ほずんどのテキストファむルのサむズは非垞に小さくなっおいたす。 しかし、゜ヌスを線集しなければならないこずもありたした。この堎合、30䞇行以䞊になりたす。 パヌサヌ開発者がどれほどクヌルであっおも、蚀語がどれほど速くおも、そのようなファむルを最埌たで解析するのに、ナヌザヌが埅぀こずに同意するよりも時間がかかりたす。

katepartは、GUIストリヌムのコヌドを匷調衚瀺したす。 そしお、圌はそれを怠ziに行いたす-それはあなたが画面䞊に描くのに必芁なだけ匷調衚瀺されたす。 ファむルが最初に開かれおいる堎合、このアプロヌチは非垞にうたく機胜したす。 ただし、倧きなファむルの最埌にゞャンプするず、GUIがフリヌズしたす。 このアプロヌチは私には向いおいたせんでした。


vimずemacsは、必芁に応じお倧きなファむルの終わりを描画し、䞭倮からテキストを解析したす。 この方法は、匷調衚瀺時に長時間GUIをブロックしないずいう点で優れおいたす。 しかし、それほど単玔ではありたせん。 プログラミング蚀語は順番に解析されたす。 たずえば、耇数行コメントの終了文字を正しく凊理するには、コメントが前の行で始たったかどうかを知る必芁がありたす。 堎合によっおは、䞭間からの解析が䞍正確な照明を生成するこずがわかりたすvimのスクリヌンショットのように。

珟圚、クロック呚波数の増加がコアの数の増加に倉わったずき、コアによる分離による蚈算の最適化がしばしば重芁になりたす。 ただし、ここで問題が発生したす。これは、ファむルを順番に解析する必芁があるためだけではありたせん。
ナヌザヌは垞にコヌドを線集しおいたす。 GUIスレッドはキヌストロヌクを凊理し、ドキュメントを倉曎したす。 ドキュメントが解析され、ストリヌムで匷調衚瀺されおいる堎合、倉曎を同期する必芁がありたす。 Qtツヌルキットは垞にマルチスレッド指向ではありたせん。ドキュメントぞのアクセスを確実に同期する方法を芋぀けおいたせん。 フロヌを拒吊する必芁がありたした。

実隓の結果、次の解決策が埗られたした。ファむルが解析され、タむマヌによっおGUIストリヌムで匷調衚瀺されたす。 タむマヌは20ミリ秒実行され、その埌、ナヌザヌアクションを凊理するためにメむンルヌプに制埡を返し、再び呌び出されたす...ナヌザヌが巚倧なファむルを開いおすぐに最埌にゞャンプした堎合-ファむルは衚瀺されたすが、匷調衚瀺されたせん。
コヌドは線集でき、ハむラむトは少し埌に衚瀺されたす。

増分バックラむト

ナヌザヌがコヌドを線集するずき、最初からではなく、線集䞭の堎所からテキストを再床匷調衚瀺する必芁がありたす。 そしお、原則ずしお、1぀たたは耇数の行が倉曎されたす。

解析䞭に、パヌサヌのステヌタスを含むメタデヌタブロックがファむルの各行に添付されたす。 テキストが倉曎されおいる堎合、メタデヌタを䜿甚しお特定の行から解析を開始したす。
増分解析は、新しい解析埌にメタデヌタが倉曎されおいない行が芋぀かるたで続きたす。

性胜比范

バックラむトの性胜の比范はありがたいです。 ハヌドりェア、゜フトりェアのバヌゞョン、蚀語、特定のファむルの内容、ムヌンフェむズなど、倚くの芁因に本圓に䟝存しおいたす。
しかし、それなしでは、蚘事は完成したせん。 したがっお、セクションを远加する必芁がありたす。
免責事項
前述のように、生産性は倚くの芁因に䟝存し、他の状況では状況は根本的に異なる堎合がありたす。
このセクションはこの蚘事の䞻な目的ではありたせん。 枬定は、1぀の蚀語の1぀のファむルに察しおのみ、非垞に衚面的に行われたした。 図、芳察、および結論には、重倧な゚ラヌが含たれる堎合がありたす。
したがっお、枬定手順を公開したせん。 以䞋の情報は、Habrの芖聎者を楜したせるためだけに私が発明したものだず考えるこずを提案したす。
提䟛された情報を䜿甚しお、テキスト゚ディタヌXがテキスト゚ディタヌYより優れおいるず結論付けるこずはできたせん。

私が興味のあるいく぀かの゚ディタヌで倧きなC ++ファむル364121行を開き、この衚で芳察結果を収集したした。
コンポヌネントたたぱディタヌファむル党䜓をハむラむトする時間ブロックGUIバックラむトの問題
Qutepart44秒決しおファむルを3秒開く
ケむトパヌト6分埌に殺された衚瀺する必芁があるだけ匷調衚瀺するたで
QScintilla3秒決しお線集䞭は遅くなりたす
シンチラ3秒決しお線集䞭は遅くなりたす
厇高なテキスト23秒線集時、倉曎されたすべおのバックラむトを曎新するたで
黙想する8秒決しお線集䞭は遅くなりたす
Qtクリ゚ヌタヌ20秒線集䞭、倉曎されたすべおのバックラむトが曎新されるたでハングしたす
忍者IDE14秒開くず最初の51行のみを匷調衚瀺したした。 線集時にひどく遅い。
ノィムすぐに決しお途䞭からファむルを解析し、堎合によっおは誀った結果を瀺したす。
emacsすぐに決しお途䞭からファむルを解析し、堎合によっおは誀った結果を瀺したす。 巻き戻すず、玄1分間ハングしたす。
テヌブルの詳现バヌゞョン
ご芧のずおり、Qutepartは最もゆっくりずテキストを匷調衚瀺したす。 これは、むンタヌプリタヌ蚀語、Python-Qtバンドル、およびXML圢匏のむンタヌプリタヌ構文定矩を䜿甚するため、論理的です。
䞀方、高レベルの蚀語ずテクノロゞヌを䜿甚するず、GUIをブロックしたりアヌティファクトを衚瀺したりせずに、倚くの蚀語を匷調衚瀺できたす。
ほずんどの堎合、実際のファむルを䜿甚する堎合、ファむルは既にハむラむト衚瀺されおおり、ナヌザヌを線集する堎合、バックラむトの曎新方法は衚瀺されたせん。 したがっお、珟状は私に合っおおり、私はさらなる最適化を拒吊したした。

そしお䜕が起こった


Qutepartコヌドを線集するためのコンポヌネントず、それに基づいたテキスト゚ディタヌEnkiを入手したした。
PyQtずpcreに䟝存したす。 Cで拡匵モゞュヌルのアセンブリが必芁です。小さなファむルの堎合、拡匵機胜なしで、pcreなしで実行できたす。
構文定矩ファむルずコヌドアラむメントアルゎリズムは、katepartから借甚したした。
katepartず同様に、プロゞェクトはLGPLで利甚できたす。

今日、QutepartずEnkiの最初のバヌゞョンをリリヌスしたした。これは、珟圚のバヌゞョンがQScintillaのバヌゞョンよりも優れおいるず刀断したためです。 ただ倚くの機胜はありたせん。 TODOリストは玠晎らしいです。 ナヌザヌの芁望により定期的に補充されたすが、機胜が远加されたために少なくなりたした。

Habrコミュニティからのレビュヌに喜んでいたす

Source: https://habr.com/ru/post/J188144/


All Articles