Re: partial fix for 687105 setcolorspace optimizationproblem
"Igor V. Melichev" <[email protected]> Wed, 23 Jun 2004 12:07:01 +0400
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
Dan,
> The use of a maximum recursion depth is a simple solution to this
> situation.
Actually the use of a maximum recursion depth is a simple way
to get an exponential time expense.
/buildlattice % <obj> m <lattice>
{
30 {
dup 2 array astore
} repeat
} bind def
/x buildlattice
16 string exch 30 exch
objectmd5sum % computes an md5 sum of 2^30 objects.
%
/x buildlattice 16 string exch 28 exch objectmd5sum
/y buildlattice 16 string exch 28 exch objectmd5sum
eq % gives a wrong result (true) after 2^29 iterations.
If you want my opinion, I believe that such kind of
programming may be acceptable for a first year student exercise,
but it is definitely unacceptable in a software.
I assume "ware" is something to be sold.
> It is very easy to create PostScript objects that point back to
> themselves.
In my example none of objects points back to itself,
neither directly nor indirectly.
> A possible solution to this problem would be to create an internal copy
> of the color space object.
Excellent. It allows to apply the strong equality.
> There are other solutions which are more elegant but they
> are also more complicated to implement.
Not sure what do you mean saying "more complicated".
I will explain my algorithm in a pseudocode.
input : any 2 PS objects o1, o2
output : true if they are isomorphic or equal, false otherwise.
CPU expense : O(n * log(n))
{
Allocate a temporary dictionary d. Use a reasonable initial size of 100 entries.
r = is_isomprphic(o1, o2, d);
Free d;
return r;
}
bool is_isomprphic(o1, o2, d)
{
If (o1 == o2) return true;
if (d(o1) exists and d(o1) == o2) return true;
if (d(o1) exists) return false;
if (type(o1) == arraytype || type(o1) == packedarraytype) return compare_arrays(o1, o2, d);
if (type(o1) == dicttype) return compare_dicts(o1, o2, d);
return false;
}
bool compare_arrays(o1, o2, d)
{ if (type(o2) != arraytype) return false;
if (size(o1) != size(o2)) return false;
for (int i = 0; i < size(o1); i++)
if (!is_isomorphic(o1[i], o2[i], d))
return false;
d[o1]:=o2; /* .growput */
return true;
}
bool compare_dicts(o1, o2, d)
{ if (type(o2) != dicttype) return false;
if (size(o1) != size(o2)) return false;
for (all {key, val} in o1) {
if (!exist(o2[key]))
return false;
if (!is_isomorphic(val, o2[key], d))
return false;
}
d[o1]:=o2; /* .growput */
return true;
}
Hope this helps.
Note that 'd' works for .objectmd5sum as well.
This may be coded in either PS or C, but the PS implementation
has one unpleasant feature : it creates a garbage with
thrown temporary dictionaries.
Apply save, restore against it.
Igor.
----- Original Message -----
From: "Dan Coby" <[email protected]>
To: "Igor V. Melichev" <[email protected]>; "Gs-Code-Review" <[email protected]>
Sent: Wednesday, June 23, 2004 2:15 AM
Subject: RE: [gs-code-review] partial fix for 687105 setcolorspace optimizationproblem (xefitra)
>
> Igor,
>
> >I'm strongly against this approach because it substitutes a strong
> >equality with a probabilistic comparison.
> >So formally it can't fix the reported problem in general,
> >but only reduces the probability of the failure.
>
> Since the MD5 sum creates a 128 bit value (128 bits holds numbers
> greater than 10**38) the odds are very small that a mistake would
> occur even if all of our users were constantly running Ghostscript and
> had been doing so since the beginning of the universe. (The current
> estimated age of the universe is 13.7 x 10**9 years.) I consider
> this to be adequate.
>
>
> >Also the strong equality takes a smaller processor time
> >(1) with non-equal objects, (2) with same objects or when
> >a part of compared object appears same, (3) due to not
> >performing a hashing of tiny pieces of source objects.
>
> I also do not like the extra CPU time required for calculating the
> MD5 sum. However with a PostScript strong equality operator (which
> you suggest just below) and with equal objects, the strong equality
> can take longer due to the overhead of the PostScript interpreter.
> The worst case situation occurs with files that are repeatedly
> setting the color space to the same thing. I am not sure how the
> execution time of the two methods would actually compare. The
> execution time of the strong equality operator could be reduced by
> implementing it in C instead of PostScript (however you also are
> objecting to creating new C operators - see below).
>
>
> >if you code a strong equality in Postscript,
> >you can store the path in estack, which works
> >with no recursion depth limit artifact.
>
> It is very easy to create PostScript objects that point back to
> themselves. A simple example is an array which has an entry which is
> the array. Without some method for limiting recursion, then we would
> have an infinite loop. This happens now with the === operator. I.e.
> try: 1 array dup dup 0 exch put ===
>
> The use of a maximum recursion depth is a simple solution to this
> situation. There are other solutions which are more elegant but they
> are also more complicated to implement.
>
>
> >Also there is no need to add a new operator to the interpreter.
> >At last, the strong comparison doesn't need tricks with
> >qsort.
>
> I am not bothered by adding another C operator nor do I consider the
> qsort logic 'tricky'.
>
>
> >Can you bring any objections against implementing the strong equality ?
>
> 1. See my previous comment about the execution time of the strong
> equality operator.
>
> 2. See my comments below about the fact that we do not have a color
> space object that really represents the currently installed color
> space.
>
>
> >BUG:
> >obj_string_data can't apply to dictionary entries,
> >which have keys of one of the following types :
> >number, null, dictionary, FID. So either zobjectmd5sum
> >has a smaller domain or compare_key_names
> >to be rewritten.
>
> Yes, this is a problem in the current implementation. I had only
> considered the cases where keys are names or strings. Thank you.
>
>
> >> Two PostScript objects can be compared for equality by first
> >> creating an MD5 sum for each object and then comparing the two
> >> sums.
> >
> >The md5 sum would have some use if the compared objects
> >don't exist simultaneously. But it isn't true with 687105.
>
> That is actually the situation that we have here. As Alex's bug report
> shows, the reason that the current color space equality check is failing
> to operate properly is because the PostScript color space object is being
> modified after the color space was installed in the graphics library. But
> the real requirement of the setcolorspace optimization logic is that we
> need to be able to compare a new color space object with the color space
> that was installed.
>
> My plan for the implementation of the remainder of the fix for this problem
> was to calculate the MD5 sum when a color space is installed and to save
> this sum in the graphics state.
>
>
> A final note:
>
> Alex does not mention it directly but this discussion and Alex's example
> also point out that if a file modifies the color space object after a
> color space is installed and then does a 'currentcolorspace', the modified
> object will be returned.
>
> A possible solution to this problem would be to create an internal copy
> of the color space object. It would be necessary to clone all of the
> subobjects along with the top level object. It is also necessary to copy
> the internal color space object again when 'currentcolorspace' is executed
> since we cannot return the internal object. If we returned the original
> object, then it could be modified by the file. This also has the
> disadvantage of a nasty CPU penalty for creating these objects.
>
>
> Dan
>
>
> -----Original Message-----
> From: Igor V. Melichev [mailto:[email protected]]
> Sent: Tuesday, June 22, 2004 9:26 AM
> To: [email protected]; Gs-Code-Review
> Subject: Re: [gs-code-review] partial fix for 687105 setcolorspace
> optimizationproblem
>
>
> I'm strongly against this approach because it substitutes a strong
> equality with a probabilistic comparison.
> So formally it can't fix the reported problem in general,
> but only reduces the probability of the failure.
> Also the strong equality takes a smaller processor time
> (1) with non-equal objects, (2) with same objects or when
> a part of compared object appears same, (3) due to not
> performing a hashing of tiny pieces of source objects.
> if you code a strong equality in Postscript,
> you can store the path in estack, which works
> with no recursion depth limit artifact.
> Also there is no need to add a new operator to the interpreter.
> At last, the strong comparison doesn't need tricks with
> qsort.
>
> Can you bring any objections against implementing the strong equality ?
>
> BUG:
> obj_string_data can't apply to dictionary entries,
> which have keys of one of the following types :
> number, null, dictionary, FID. So either zobjectmd5sum
> has a smaller domain or compare_key_names
> to be rewritten.
>
> > Two PostScript objects can be compared for equality by first
> > creating an MD5 sum for each object and then comparing the two
> > sums.
>
> The md5 sum would have some use if the compared objects
> don't exist simultaneously. But it isn't true with 687105.
>
> Igor.
>
>
> ----- Original Message -----
> From: "Dan Coby" <[email protected]>
> To: "Gs-Code-Review" <[email protected]>
> Sent: Saturday, June 19, 2004 11:35 AM
> Subject: [gs-code-review] partial fix for 687105 setcolorspace optimizationproblem
>
>
> >
> > Partial fix for 687105 setcolorspace optimization problem.
> >
> > DETAILS:
> >
> > Currently the PostScript interpreter checks to see if a color
> > space is changed whenever a call is made to setcolorspace.
> > This greatly increase throughput on some files which set the
> > same color space before every drawing operation.
> >
> > However the logic for comparing if two color spaces are the
> > same is not perfect. It misses the case where a color space
> > is specified by an array and one or more of the elements in
> > the array is changed afterward.
> >
> > This change creates a new PostScript operator which calculates
> > an MD5 sum for any PostScript object. The description of this
> > operator is in src/zmd5.c. See the comments prior to
> > zobjectmd5sum.
> >
> > Two PostScript objects can be compared for equality by first
> > creating an MD5 sum for each object and then comparing the two
> > sums.
> >
> > Since this operator may be used for other purposes besides
> > comparing color spaces, I am submitting just this operator to
> > code review.
> >
> >
> > Dan
>
>
> --------------------------------------------------------------------------------
>
>
> > _______________________________________________
> > gs-code-review mailing list
> > [email protected]
> > http://www.ghostscript.com/mailman/listinfo/gs-code-review
> >
>
>