// Copyright 2008 the V8 project authors. All rights reserved. // Copyright 1996 John Maloney and Mario Wolczko.
// This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// This implementation of the DeltaBlue benchmark is derived // from the Smalltalk implementation by John Maloney and Mario // Wolczko. Some parts have been translated directly, whereas // others have been modified more aggresively to make it feel // more like a JavaScript program.
var DeltaBlue = new BenchmarkSuite('DeltaBlue', [66118], [ new Benchmark('DeltaBlue', true, false, 4400, deltaBlue)
]);
value: function (shuper) { function Inheriter() { }
Inheriter.prototype = shuper.prototype; this.prototype = new Inheriter(); this.superConstructor = shuper;
}
});
function OrderedCollection() { this.elms = new Array();
}
OrderedCollection.prototype.add = function (elm) { this.elms.push(elm);
}
OrderedCollection.prototype.at = function (index) { returnthis.elms[index];
}
OrderedCollection.prototype.size = function () { returnthis.elms.length;
}
OrderedCollection.prototype.removeFirst = function () { returnthis.elms.pop();
}
OrderedCollection.prototype.remove = function (elm) { var index = 0, skipped = 0; for (var i = 0; i < this.elms.length; i++) { var value = this.elms[i]; if (value != elm) { this.elms[index] = value;
index++;
} else {
skipped++;
}
} for (var i = 0; i < skipped; i++) this.elms.pop();
}
/** *Removesalltracesofcfromthisvariable.
*/
Variable.prototype.removeConstraint = function (c) { this.constraints.remove(c); if (this.determinedBy == c) this.determinedBy = null;
}
/* --- * *Planner
* --- */
/** *TheDeltaBlueplanner
*/ function Planner() { this.currentMark = 0;
}
/** *Attempttosatisfythegivenconstraintand,ifsuccessful, *incrementallyupdatethedataflowgraph.Details:Ifsatifying *theconstraintissuccessful,itmayoverrideaweakerconstraint *onitsoutput.Thealgorithmattemptstoresatisfythat *constraintusingsomeothermethod.Thisprocessisrepeated *untileithera)itreachesavariablethatwasnotpreviously *determinedbyanyconstraintorb)itreachesaconstraintthat *istooweaktobesatisfiedusinganyofitsmethods.The *variablesofconstraintsthathavebeenprocessedaremarkedwith *auniquemarkvaluesothatweknowwherewe'vebeen.Thisallows *thealgorithmtoavoidgettingintoaninfiniteloopevenifthe *constraintgraphhasaninadvertentcycle.
*/
Planner.prototype.incrementalAdd = function (c) { var mark = this.newMark(); var overridden = c.satisfy(mark); while (overridden != null)
overridden = overridden.satisfy(mark);
}
/** *Entrypointforretractingaconstraint.Removethegiven *constraintandincrementallyupdatethedataflowgraph. *Details:Retractingthegivenconstraintmayallowsomecurrently *unsatisfiabledownstreamconstrainttobesatisfied.Wethereforecollect *alistofunsatisfieddownstreamconstraintsandattemptto *satisfyeachoneinturn.Thislististraversedbyconstraint *strength,strongestfirst,asaheuristicforavoiding *unnecessarilyaddingandthenoverridingweakconstraints. *Assume:cissatisfied.
*/
Planner.prototype.incrementalRemove = function (c) { var out = c.output();
c.markUnsatisfied();
c.removeFromGraph(); var unsatisfied = this.removePropagateFrom(out); var strength = Strength.REQUIRED; do { for (var i = 0; i < unsatisfied.size(); i++) { var u = unsatisfied.at(i); if (u.strength == strength) this.incrementalAdd(u);
}
strength = strength.nextWeaker();
} while (strength != Strength.WEAKEST);
}
/** *Extractaplanforresatisfactionstartingfromthegivensource *constraints,usuallyasetofinputconstraints.Thismethod *assumesthatstayoptimizationisdesired;theplanwillcontain *onlyconstraintswhoseoutputvariablesarenotstay.Constraints *thatdonocomputation,suchasstayandeditconstraints,are *notincludedintheplan. *Details:Theoutputsofaconstraintaremarkedwhenitisadded *totheplanunderconstruction.Aconstraintmaybeappendedto *theplanwhenallitsinputvariablesareknown.Avariableis *knownifeithera)thevariableismarked(indicatingthathas *beencomputedbyaconstraintappearingearlierintheplan),b) *thevariableis'stay'(i.e.itisaconstantatplanexecution *time),orc)thevariableisnotdeterminedbyany *constraint.Thelastprovisionisforpaststatesofhistory *variables,whicharenotstaybutwhicharealsonotcomputedby *anyconstraint. *Assume:sourcesareallsatisfied.
*/
Planner.prototype.makePlan = function (sources) { var mark = this.newMark(); var plan = new Plan(); var todo = sources; while (todo.size() > 0) { var c = todo.removeFirst(); if (c.output().mark != mark && c.inputsKnown(mark)) {
plan.addConstraint(c);
c.output().mark = mark; this.addConstraintsConsumingTo(c.output(), todo);
}
} return plan;
}
/** *Extractaplanforresatisfyingstartingfromtheoutputofthe *givenconstraints,usuallyasetofinputconstraints.
*/
Planner.prototype.extractPlanFromConstraints = function (constraints) { var sources = new OrderedCollection(); for (var i = 0; i < constraints.size(); i++) { var c = constraints.at(i); if (c.isInput() && c.isSatisfied()) // not in plan already and eligible for inclusion
sources.add(c);
} returnthis.makePlan(sources);
}
/** *Recomputethewalkaboutstrengthsandstayflagsofallvariables *downstreamofthegivenconstraintandrecomputetheactual *valuesofallvariableswhosestayflagistrue.Ifacycleis *detected,removethegivenconstraintandanswer *false.Otherwise,answertrue. *Details:Cyclesaredetectedwhenamarkedvariableis *encountereddownstreamofthegivenconstraint.Thesenderis *assumedtohavemarkedtheinputsofthegivenconstraintwith *thegivenmark.Thus,encounteringamarkednodedownstreamof *theoutputconstraintmeansthatthereisapathfromthe *constraint'soutputtooneofitsinputs.
*/
Planner.prototype.addPropagate = function (c, mark) { var todo = new OrderedCollection();
todo.add(c); while (todo.size() > 0) { var d = todo.removeFirst(); if (d.output().mark == mark) { this.incrementalRemove(c); returnfalse;
}
d.recalculate(); this.addConstraintsConsumingTo(d.output(), todo);
} returntrue;
}
/** *Updatethewalkaboutstrengthsandstayflagsofallvariables *downstreamofthegivenconstraint.Answeracollectionof *unsatisfiedconstraintssortedinorderofdecreasingstrength.
*/
Planner.prototype.removePropagateFrom = function (out) {
out.determinedBy = null;
out.walkStrength = Strength.WEAKEST;
out.stay = true; var unsatisfied = new OrderedCollection(); var todo = new OrderedCollection();
todo.add(out); while (todo.size() > 0) { var v = todo.removeFirst(); for (var i = 0; i < v.constraints.size(); i++) { var c = v.constraints.at(i); if (!c.isSatisfied())
unsatisfied.add(c);
} var determining = v.determinedBy; for (var i = 0; i < v.constraints.size(); i++) { var next = v.constraints.at(i); if (next != determining && next.isSatisfied()) {
next.recalculate();
todo.add(next.output());
}
}
} return unsatisfied;
}
Planner.prototype.addConstraintsConsumingTo = function (v, coll) { var determining = v.determinedBy; var cc = v.constraints; for (var i = 0; i < cc.size(); i++) { var c = cc.at(i); if (c != determining && c.isSatisfied())
coll.add(c);
}
}
/* --- * *Plan
* --- */
/** *APlanisanorderedlistofconstraintstobeexecutedinsequence *toresatisfyallcurrentlysatisfiableconstraintsinthefaceof *oneormorechanginginputs.
*/ function Plan() { this.v = new OrderedCollection();
}
Plan.prototype.addConstraint = function (c) { this.v.add(c);
}
Plan.prototype.size = function () { returnthis.v.size();
}
Plan.prototype.constraintAt = function (index) { returnthis.v.at(index);
}
Plan.prototype.execute = function () { for (var i = 0; i < this.size(); i++) { var c = this.constraintAt(i);
c.execute();
}
}
/* --- * *Main
* --- */
/** *ThisisthestandardDeltaBluebenchmark.Alongchainofequality *constraintsisconstructedwithastayconstraintononeend.An *editconstraintisthenaddedtotheoppositeendandthetimeis *measuredforaddingandremovingthisconstraint,andextracting *andexecutingaconstraintsatisfactionplan.Therearetwocases. *Incase1,theaddedconstraintisstrongerthanthestay *constraintandvaluesmustpropagatedowntheentirelengthofthe *chain.Incase2,theaddedconstraintisweakerthanthestay *constraintsoitcannotbeaccomodated.Thecostinthiscaseis, *ofcourse,verylow.Typicalsituationsliesomewherebetweenthese *twoextremes.
*/ function chainTest(n) {
planner = new Planner(); var prev = null, first = null, last = null;
// Build chain of n equality constraints for (var i = 0; i <= n; i++) { var name = "v" + i; var v = new Variable(name); if (prev != null) new EqualityConstraint(prev, v, Strength.REQUIRED); if (i == 0) first = v; if (i == n) last = v;
prev = v;
}
new StayConstraint(last, Strength.STRONG_DEFAULT); var edit = new EditConstraint(first, Strength.PREFERRED); var edits = new OrderedCollection();
edits.add(edit); var plan = planner.extractPlanFromConstraints(edits); for (var i = 0; i < 100; i++) {
first.value = i;
plan.execute(); if (last.value != i)
alert("Chain test failed.");
}
}
/** *Thistestconstructsatwosetsofvariablesrelatedtoeach *otherbyasimplelineartransformation(scaleandoffset).The *timeismeasuredtochangeavariableoneithersideofthe *mappingandtochangethescaleandoffsetfactors.
*/ function projectionTest(n) {
planner = new Planner(); var scale = new Variable("scale", 10); var offset = new Variable("offset", 1000); var src = null, dst = null;
var dests = new OrderedCollection(); for (var i = 0; i < n; i++) {
src = new Variable("src" + i, i);
dst = new Variable("dst" + i, i);
dests.add(dst); new StayConstraint(src, Strength.NORMAL); new ScaleConstraint(src, scale, offset, dst, Strength.REQUIRED);
}
change(src, 17); if (dst.value != 1170) alert("Projection 1 failed");
change(dst, 1050); if (src.value != 5) alert("Projection 2 failed");
change(scale, 5); for (var i = 0; i < n - 1; i++) { if (dests.at(i).value != i * 5 + 1000)
alert("Projection 3 failed");
}
change(offset, 2000); for (var i = 0; i < n - 1; i++) { if (dests.at(i).value != i * 5 + 2000)
alert("Projection 4 failed");
}
}
function change(v, newValue) { var edit = new EditConstraint(v, Strength.PREFERRED); var edits = new OrderedCollection();
edits.add(edit); var plan = planner.extractPlanFromConstraints(edits); for (var i = 0; i < 10; i++) {
v.value = newValue;
plan.execute();
}
edit.destroyConstraint();
}
// Global variable holding the current planner. var planner = null;
function deltaBlue() {
chainTest(100);
projectionTest(100);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.