1

Postscript 配列の最大サイズはありますか?

問題なくゴーストビューに表示される配列を含む PS ドキュメントを作成しました。

ただし、この配列内のアイテムの数が増えると、ghostview は次の例外を発生させます。

ERROR: /stackoverflow in -file-
Operand stack:
   --nostringval--
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1   3   %oparray_pop   1   3   %oparray_pop   1   3   %oparray_pop   1   3   %oparray_pop   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push
Dictionary stack:
   --dict:1122/1686(ro)(G)--   --dict:0/20(G)--   --dict:122/200(L)--
Current allocation mode is local
Last OS error: 2
Current file position is 301163
ESP Ghostscript 815.02: Unrecoverable error, exit code 1
4

1 に答える 1

3

配列の最大長は65535です。これは文字列の最大長でもあります。しかし、それはここでは問題ではないようです。

Postscript Level 2 では、スタック サイズの制限が取り除かれたため、仮想メモリ システムが管理できるサイズに自動的に拡張されます。/stackoverflow エラーが発生した場合。インタプリタを少なくともレベル 2 (1991) 標準にアップグレードする必要があります。

編集:とはいえ、アップグレードがオプションでない場合、問題を回避する方法があります。

スタックが静的に割り当てられているため、制限が発生する可能性が最も高くなります。ソース コードにアクセスできる場合は、単純にサイズを大きくしてインタープリターを再コンパイルできます。PLRM 1ed で引用されている制限は 500 です。

別のオプションは、スタックの操作方法を変更することです (より難しい)。を使用して 1000 要素の配列を構築できない場合、[]または配列を{}割り当て ( 1000 array)、通常どおりに構築されたスライスで埋めることができます ( dup dup 0 [ 0 1 .. 450 ] putinterval dup dup 450 [ 451 452 .. 900 ] putinterval dup dup 900 [ 901 902 .. 999 ] putinterval)。マークもスタックのスペースを占有することに注意してください。特定の演算子は実際にはプロシージャであり、操作するにはスタック領域が必要です。

編集:配列が本当に巨大な場合、配列スライスが合計メモリ制限に達する可能性があります。スタックが増えていなければ、おそらくガベージ コレクションも行われていないからです。上記の方法では、1000 個の配列要素が使用され、VM でアクセスできなくなります。スライスに使用packedarrayすると、この問題をある程度回避できる場合があります。

次のステップは、一時配列を作成せずにデータを配列にロードできる putinterval とpackedarray のハイブリッドのように機能するプロシージャを作成することです。低レベルの機能を高レベルで再実装しているため、これは遅くなる可能性があります。

これが最初の刺身です。( を使用して) 先読みしcurrentfile token、各要素を配列の後続の位置に配置します。arrayfillcurrentfile が最初の要素を見つけることができるように (ソース行の残りの部分は内部スキャナ バッファにあります) 、ソース行の最後の単語 ( などimage) にする必要があります。

% array index count  arrayfill(NL)  array
% elem_0 elem_1 ..
% elem_count-1
/arrayfill { %a i c
    1 index add 1 sub %a ini fin
    1 exch { %a i
        2 copy %a i a i
        currentfile token pop %a i a i el
        put %a i
        pop %a
    } for
} def

%example
5 array 0 5 arrayfill
(0) (1) (2) (3) (4)
{=} forall
于 2011-09-29T14:21:45.767 に答える