Title: [220893] trunk/PerformanceTests
Revision
220893
Author
[email protected]
Date
2017-08-17 17:56:59 -0700 (Thu, 17 Aug 2017)

Log Message

Add a Unicode test to RexBench that matches non-BMP characters
https://bugs.webkit.org/show_bug.cgi?id=175697

Reviewed by JF Bastien.

Added a new sub test that simulates 5 card stud poker.  This test uses the Unicode playing
cards code points, U+1F0A1..U+1F0DE, as the card representation.  The scoring of hands is
done using three regular expressions, one to check for a flush, one to check for straights
and one to check for pairs, three of a kind and four of a kind.

* RexBench/UniPoker: Added.
* RexBench/UniPoker/benchmark.js: Added.
(UniPokerBenchmark):
(UniPokerBenchmark.prototype.setup.):
(UniPokerBenchmark.prototype.setup.Math.random):
(UniPokerBenchmark.prototype.setup):
(UniPokerBenchmark.prototype.runOnce):
(UniPokerBenchmark.prototype.validate):
* RexBench/UniPoker/expected.js: Added.
(PlayerExpectation):
(PlayerExpectation.prototype.validate):
* RexBench/UniPoker/poker.js: Added.
(CardDeck):
(CardDeck.prototype.newDeck):
(CardDeck.prototype.shuffle):
(CardDeck.prototype.dealOneCard):
(CardDeck.cardRank):
(CardDeck.cardName):
(Hand):
(Hand.prototype.clear):
(Hand.prototype.takeCard):
(Hand.prototype.score):
(Hand.prototype.get rank):
(Hand.prototype.toString):
(Player):
(Player.prototype.scoreHand):
(Player.prototype.wonHand):
(Player.prototype.get name):
(Player.prototype.get hand):
(Player.prototype.get wins):
(Player.prototype.get handTypeCounts):
(playHands):
* RexBench/about.html:
* RexBench/cli.js:
* RexBench/glue.js:
(driver.reportResult):
* RexBench/index.html:
* RexBench/unipoker_benchmark.js: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/PerformanceTests/ChangeLog (220892 => 220893)


--- trunk/PerformanceTests/ChangeLog	2017-08-18 00:54:17 UTC (rev 220892)
+++ trunk/PerformanceTests/ChangeLog	2017-08-18 00:56:59 UTC (rev 220893)
@@ -1,3 +1,54 @@
+2017-08-17  Michael Saboff  <[email protected]>
+
+        Add a Unicode test to RexBench that matches non-BMP characters
+        https://bugs.webkit.org/show_bug.cgi?id=175697
+
+        Reviewed by JF Bastien.
+
+        Added a new sub test that simulates 5 card stud poker.  This test uses the Unicode playing
+        cards code points, U+1F0A1..U+1F0DE, as the card representation.  The scoring of hands is
+        done using three regular expressions, one to check for a flush, one to check for straights
+        and one to check for pairs, three of a kind and four of a kind.
+
+        * RexBench/UniPoker: Added.
+        * RexBench/UniPoker/benchmark.js: Added.
+        (UniPokerBenchmark):
+        (UniPokerBenchmark.prototype.setup.):
+        (UniPokerBenchmark.prototype.setup.Math.random):
+        (UniPokerBenchmark.prototype.setup):
+        (UniPokerBenchmark.prototype.runOnce):
+        (UniPokerBenchmark.prototype.validate):
+        * RexBench/UniPoker/expected.js: Added.
+        (PlayerExpectation):
+        (PlayerExpectation.prototype.validate):
+        * RexBench/UniPoker/poker.js: Added.
+        (CardDeck):
+        (CardDeck.prototype.newDeck):
+        (CardDeck.prototype.shuffle):
+        (CardDeck.prototype.dealOneCard):
+        (CardDeck.cardRank):
+        (CardDeck.cardName):
+        (Hand):
+        (Hand.prototype.clear):
+        (Hand.prototype.takeCard):
+        (Hand.prototype.score):
+        (Hand.prototype.get rank):
+        (Hand.prototype.toString):
+        (Player):
+        (Player.prototype.scoreHand):
+        (Player.prototype.wonHand):
+        (Player.prototype.get name):
+        (Player.prototype.get hand):
+        (Player.prototype.get wins):
+        (Player.prototype.get handTypeCounts):
+        (playHands):
+        * RexBench/about.html:
+        * RexBench/cli.js:
+        * RexBench/glue.js:
+        (driver.reportResult):
+        * RexBench/index.html:
+        * RexBench/unipoker_benchmark.js: Added.
+
 2017-08-16  Mathias Bynens  <[email protected]>
 
         Speedometer: Update Angular 1 TodoMVC example to v1.6.5

Added: trunk/PerformanceTests/RexBench/UniPoker/benchmark.js (0 => 220893)


--- trunk/PerformanceTests/RexBench/UniPoker/benchmark.js	                        (rev 0)
+++ trunk/PerformanceTests/RexBench/UniPoker/benchmark.js	2017-08-18 00:56:59 UTC (rev 220893)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+"use strict";
+
+class UniPokerBenchmark extends Benchmark {
+    constructor(verbose = 0)
+    {
+        super(verbose);
+        this._players = [];
+    }
+
+    setup()
+    {
+        Math.random = (function() {
+            var seed = 49734321;
+            return function() {
+                // Robert Jenkins' 32 bit integer hash function.
+                seed = ((seed + 0x7ed55d16) + (seed << 12))  & 0xffffffff;
+                seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
+                seed = ((seed + 0x165667b1) + (seed << 5))   & 0xffffffff;
+                seed = ((seed + 0xd3a2646c) ^ (seed << 9))   & 0xffffffff;
+                seed = ((seed + 0xfd7046c5) + (seed << 3))   & 0xffffffff;
+                seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
+                return (seed & 0xfffffff) / 0x10000000;
+            };
+        })();
+
+        this._players = [];
+        this._players.push(new Player("Player 1"));
+        this._players.push(new Player("Player 2"));
+        this._players.push(new Player("Player 3"));
+        this._players.push(new Player("Player 4"));
+    }
+
+    runOnce()
+    {
+        playHands(this._players);
+    }
+
+    validate()
+    {
+        if (this._players.length != playerExpectations.length)
+            throw "Expect " + playerExpectations.length + ", but actually have " + this._players.length;
+
+        for (let playerIdx = 0; playerIdx < playerExpectations.length; playerIdx++)
+            playerExpectations[playerIdx].validate(this._players[playerIdx]);
+    }
+}

Added: trunk/PerformanceTests/RexBench/UniPoker/expected.js (0 => 220893)


--- trunk/PerformanceTests/RexBench/UniPoker/expected.js	                        (rev 0)
+++ trunk/PerformanceTests/RexBench/UniPoker/expected.js	2017-08-18 00:56:59 UTC (rev 220893)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+"use strict";
+
+class PlayerExpectation
+{
+    constructor(wins, handTypeCounts)
+    {
+        this._wins = wins;
+        this._handTypeCounts = handTypeCounts;
+    }
+
+    validate(player)
+    {
+        if (player.wins != this._wins)
+            throw "Expected " + player.name + " to have " + this._wins + ", but they have " + player.wins;
+
+        let actualHandTypeCounts = player.handTypeCounts;
+        if (this._handTypeCounts.length != actualHandTypeCounts.length)
+            throw "Expected " + player.name + " to have " + this._handTypeCounts.length + " hand types, but they have " + actualHandTypeCounts.length;
+
+        for (let handTypeIdx = 0; handTypeIdx < this._handTypeCounts.length; handTypeIdx++) {
+            if (this._handTypeCounts[handTypeIdx] != actualHandTypeCounts[handTypeIdx]) {
+                throw "Expected " + player.name + " to have " + this._handTypeCounts[handTypeIdx] + " " + this._handTypes[handTypeIdx] + " hands, but they have " + actualHandTypeCounts[handTypeIdx];
+            }
+        }
+    }
+}
+
+PlayerExpectation._handTypes = [
+    "High Cards",
+    "Pairs",
+    "Two Pairs",
+    "Three of a Kinds",
+    "Straights",
+    "Flushes",
+    "Full Houses",
+    "Four of a Kinds",
+    "Straight Flushes",
+    "Royal Flushes"
+];
+    
+var playerExpectations = [];
+
+playerExpectations.push(new PlayerExpectation(9944, [ 20065, 16861, 1875, 898, 161, 75, 58, 7, 0, 0]));
+playerExpectations.push(new PlayerExpectation(9969, [ 20142, 16782, 1891, 918, 131, 61, 60, 13, 2, 0]));
+playerExpectations.push(new PlayerExpectation(10028, [ 20123, 16816, 1936, 828, 152, 74, 54, 16, 1, 0]));
+playerExpectations.push(new PlayerExpectation(10062, [ 20082, 16801, 1933, 874, 169, 70, 61, 9, 1, 0]));

Added: trunk/PerformanceTests/RexBench/UniPoker/poker.js (0 => 220893)


--- trunk/PerformanceTests/RexBench/UniPoker/poker.js	                        (rev 0)
+++ trunk/PerformanceTests/RexBench/UniPoker/poker.js	2017-08-18 00:56:59 UTC (rev 220893)
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+"use strict";
+
+
+class CardDeck
+{
+    constructor()
+    {
+        this.newDeck();
+    }
+
+    newDeck()
+    {
+        // Make a shallow copy of a new deck
+        this._cards = CardDeck._newDeck.slice(0);
+    }
+
+    shuffle()
+    {
+        this.newDeck();
+
+        for (let index = 52; index !== 0;) {
+            // Select a random card
+            let randomIndex = Math.floor(Math.random() * index);
+            index--;
+
+            // Swap the current card with the random card
+            let tempCard = this._cards[index];
+            this._cards[index] = this._cards[randomIndex];
+            this._cards[randomIndex] = tempCard;
+        }
+    }
+
+    dealOneCard()
+    {
+        return this._cards.shift();
+    }
+
+    static cardRank(card)
+    {
+        // This returns a numeric value for a card.
+        // Ace is highest.
+
+        let rankOfCard = card.codePointAt(0) & 0xf;
+        if (rankOfCard == 0x1) // Make Aces higher than Kings
+            rankOfCard = 0xf;
+
+        return rankOfCard;
+    }
+
+    static cardName(card)
+    {      
+        if (typeof(card) == "string")
+            card = card.codePointAt(0);
+        return this._rankNames[card & 0xf];
+    }
+}
+
+CardDeck._rankNames = [
+    "", "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "", "Queen", "King"
+];
+
+CardDeck._newDeck = [
+    // Spades
+    "\u{1f0a1}", "\u{1f0a2}",  "\u{1f0a3}",  "\u{1f0a4}",  "\u{1f0a5}",
+    "\u{1f0a6}", "\u{1f0a7}",  "\u{1f0a8}",  "\u{1f0a9}",  "\u{1f0aa}",
+    "\u{1f0ab}", "\u{1f0ad}",  "\u{1f0ae}",
+    // Hearts
+    "\u{1f0b1}", "\u{1f0b2}",  "\u{1f0b3}",  "\u{1f0b4}",  "\u{1f0b5}",
+    "\u{1f0b6}", "\u{1f0b7}",  "\u{1f0b8}",  "\u{1f0b9}",  "\u{1f0ba}",
+    "\u{1f0bb}", "\u{1f0bd}",  "\u{1f0be}",
+    // Clubs
+    "\u{1f0d1}", "\u{1f0d2}",  "\u{1f0d3}",  "\u{1f0d4}",  "\u{1f0d5}",
+    "\u{1f0d6}", "\u{1f0d7}",  "\u{1f0d8}",  "\u{1f0d9}",  "\u{1f0da}",
+    "\u{1f0db}", "\u{1f0dd}",  "\u{1f0de}",
+    // Diamonds
+    "\u{1f0c1}", "\u{1f0c2}",  "\u{1f0c3}",  "\u{1f0c4}",  "\u{1f0c5}",
+    "\u{1f0c6}", "\u{1f0c7}",  "\u{1f0c8}",  "\u{1f0c9}",  "\u{1f0ca}",
+    "\u{1f0cb}", "\u{1f0cd}",  "\u{1f0ce}"
+];
+
+class Hand
+{
+    constructor()
+    {
+        this.clear();
+    }
+
+    clear()
+    {
+        this._cards = [];
+        this._rank = 0;
+    }
+
+    takeCard(card)
+    {
+        this._cards.push(card);
+    }
+
+    score()
+    {
+        // Sort highest rank to lowest
+        this._cards.sort((a, b) => {
+            return CardDeck.cardRank(b) - CardDeck.cardRank(a);
+        });
+
+        let handString = this._cards.join("");
+
+        let flushResult = handString.match(Hand.FlushRegExp);
+        let straightResult = handString.match(Hand.StraightRegExp);
+        let ofAKindResult = handString.match(Hand.OfAKindRegExp);
+
+        if (flushResult) {
+            if (straightResult) {
+                if (straightResult[1])
+                    this._rank = Hand.RoyalFlush;
+                else
+                    this._rank = Hand.StraightFlush
+            } else
+                this._rank = Hand.Flush;
+
+            this._rank |= CardDeck.cardRank(this._cards[0]) << 16 | CardDeck.cardRank(this._cards[1]) << 12;
+        } else if (straightResult)
+            this._rank = Hand.Straight | CardDeck.cardRank(this._cards[0]) << 16 | CardDeck.cardRank(this._cards[1]) << 12;
+        else if (ofAKindResult) {
+            // When comparing lengths, a matched unicode character has a length of 2.
+            // Therefore expected lengths are doubled, e.g a pair will have a match length of 4.
+            if (ofAKindResult[0].length == 8)
+                this._rank = Hand.FourOfAKind | CardDeck.cardRank(this._cards[0]);
+            else {
+                // Found pair or three of a kind.  Check for two pair or full house.
+                let firstOfAKind = ofAKindResult[0];
+                let remainingCardsIndex = handString.indexOf(firstOfAKind) + firstOfAKind.length;
+                let secondOfAKindResult;
+                if (remainingCardsIndex <= 6
+                    && (secondOfAKindResult = handString.slice(remainingCardsIndex).match(Hand.OfAKindRegExp))) {
+                    if ((firstOfAKind.length == 6 && secondOfAKindResult[0].length == 4)
+                        || (firstOfAKind.length == 4 && secondOfAKindResult[0].length == 6)) {
+                        let threeOfAKindCardRank;
+                        let twoOfAKindCardRank;
+                        if (firstOfAKind.length == 6) {
+                            threeOfAKindCardRank = CardDeck.cardRank(firstOfAKind.slice(0,2));
+                            twoOfAKindCardRank = CardDeck.cardRank(secondOfAKindResult[0].slice(0,2));
+                        } else {
+                            threeOfAKindCardRank = CardDeck.cardRank(secondOfAKindResult[0].slice(0,2));
+                            twoOfAKindCardRank = CardDeck.cardRank(firstOfAKind.slice(0,2));
+                        }
+                        this._rank = Hand.FullHouse | threeOfAKindCardRank << 16 | threeOfAKindCardRank < 12 | threeOfAKindCardRank << 8 | twoOfAKindCardRank << 4 | twoOfAKindCardRank;
+                    } else if (firstOfAKind.length == 4 && secondOfAKindResult[0].length == 4) {
+                        let firstPairCardRank = CardDeck.cardRank(firstOfAKind.slice(0,2));
+                        let SecondPairCardRank = CardDeck.cardRank(secondOfAKindResult[0].slice(0,2));
+                        let otherCardRank;
+                        // Due to sorting, the other card is at index 0, 4 or 8
+                        if (firstOfAKind.codePointAt(0) == handString.codePointAt(0)) {
+                            if (secondOfAKindResult[0].codePointAt(0) == handString.codePointAt(4))
+                                otherCardRank = CardDeck.cardRank(handString.slice(8,10));
+                            else
+                                otherCardRank = CardDeck.cardRank(handString.slice(4,6));
+                        } else
+                            otherCardRank = CardDeck.cardRank(handString.slice(0,2));
+
+                        this._rank = Hand.TwoPair | firstPairCardRank << 16 | firstPairCardRank << 12 | SecondPairCardRank << 8 | SecondPairCardRank << 4 | otherCardRank;
+                    }
+                } else {
+                    let ofAKindCardRank = CardDeck.cardRank(firstOfAKind.slice(0,2));
+                    let otherCardsRank = 0;
+                    for (let card of this._cards) {
+                        let cardRank = CardDeck.cardRank(card);
+                        if (cardRank != ofAKindCardRank)
+                            otherCardsRank = (otherCardsRank << 4) | cardRank;
+                    }
+
+                    if (firstOfAKind.length == 6)
+                        this._rank = Hand.ThreeOfAKind | ofAKindCardRank << 16 | ofAKindCardRank << 12 | ofAKindCardRank << 8 | otherCardsRank;
+                    else
+                        this._rank = Hand.Pair | ofAKindCardRank << 16 | ofAKindCardRank << 12 | otherCardsRank;
+                }
+            }
+        } else {
+            this._rank = 0;
+            for (let card of this._cards) {
+                let cardRank = CardDeck.cardRank(card);
+                this._rank = (this._rank << 4) | cardRank;
+            }
+        }
+    }
+
+    get rank()
+    {
+        return this._rank;
+    }
+
+    toString()
+    {
+        return this._cards.join("");
+    }
+}
+
+Hand.FlushRegExp = new RegExp("([\u{1f0a1}-\u{1f0ae}]{5})|([\u{1f0b1}-\u{1f0be}]{5})|([\u{1f0c1}-\u{1f0ce}]{5})|([\u{1f0d1}-\u{1f0de}]{5})", "u");
+
+Hand.StraightRegExp = new RegExp("([\u{1f0a1}\u{1f0b1}\u{1f0d1}\u{1f0c1}][\u{1f0ae}\u{1f0be}\u{1f0de}\u{1f0ce}][\u{1f0ad}\u{1f0bd}\u{1f0dd}\u{1f0cd}][\u{1f0ab}\u{1f0bb}\u{1f0db}\u{1f0cb}][\u{1f0aa}\u{1f0ba}\u{1f0da}\u{1f0ca}])|[\u{1f0ae}\u{1f0be}\u{1f0de}\u{1f0ce}][\u{1f0ad}\u{1f0bd}\u{1f0dd}\u{1f0cd}][\u{1f0ab}\u{1f0bb}\u{1f0db}\u{1f0cb}][\u{1f0aa}\u{1f0ba}\u{1f0da}\u{1f0ca}][\u{1f0a9}\u{1f0b9}\u{1f0d9}\u{1f0c9}]|[\u{1f0ad}\u{1f0bd}\u{1f0dd}\u{1f0cd}][\u{1f0ab}\u{1f0bb}\u{1f0db}\u{1f0cb}][\u{1f0aa}\u{1f0ba}\u{1f0da}\u{1f0ca}][\u{1f0a9}\u{1f0b9}\u{1f0d9}\u{1f0c9}][\u{1f0a8}\u{1f0b8}\u{1f0d8}\u{1f0c8}]|[\u{1f0ab}\u{1f0bb}\u{1f0db}\u{1f0cb}][\u{1f0aa}\u{1f0ba}\u{1f0da}\u{1f0ca}][\u{1f0a9}\u{1f0b9}\u{1f0d9}\u{1f0c9}][\u{1f0a8}\u{1f0b8}\u{1f0d8}\u{1f0c8}][\u{1f0a7}\u{1f0b7}\u{1f0d7}\u{1f0c7}]|[\u{1f0aa}\u{1f0ba}\u{1f0da}\u{1f0ca}][\u{1f0a9}\u{1f0b9}\u{1f0d9}\u{1f0c9}][\u{1f0a8}\u{1f0b8}\u{1f0d8}\u{1f0c8}][\u{1f0a7}\u{1f0b7}\u{1f0d7}\u{1f0c7}][\u{1f0a6}\u{1f0b6}\u{1f0d6}\u{1f0c6}]|[
 \u{1f0a9}\u{1f0b9}\u{1f0d9}\u{1f0c9}][\u{1f0a8}\u{1f0b8}\u{1f0d8}\u{1f0c8}][\u{1f0a7}\u{1f0b7}\u{1f0d7}\u{1f0c7}][\u{1f0a6}\u{1f0b6}\u{1f0d6}\u{1f0c6}][\u{1f0a5}\u{1f0b5}\u{1f0d5}\u{1f0c5}]|[\u{1f0a8}\u{1f0b8}\u{1f0d8}\u{1f0c8}][\u{1f0a7}\u{1f0b7}\u{1f0d7}\u{1f0c7}][\u{1f0a6}\u{1f0b6}\u{1f0d6}\u{1f0c6}][\u{1f0a5}\u{1f0b5}\u{1f0d5}\u{1f0c5}][\u{1f0a4}\u{1f0b4}\u{1f0d4}\u{1f0c4}]|[\u{1f0a7}\u{1f0b7}\u{1f0d7}\u{1f0c7}][\u{1f0a6}\u{1f0b6}\u{1f0d6}\u{1f0c6}][\u{1f0a5}\u{1f0b5}\u{1f0d5}\u{1f0c5}][\u{1f0a4}\u{1f0b4}\u{1f0d4}\u{1f0c4}][\u{1f0a3}\u{1f0b3}\u{1f0d3}\u{1f0c3}]|[\u{1f0a6}\u{1f0b6}\u{1f0d6}\u{1f0c6}][\u{1f0a5}\u{1f0b5}\u{1f0d5}\u{1f0c5}][\u{1f0a4}\u{1f0b4}\u{1f0d4}\u{1f0c4}][\u{1f0a3}\u{1f0b3}\u{1f0d3}\u{1f0c3}][\u{1f0a2}\u{1f0b2}\u{1f0d2}\u{1f0c2}]|[\u{1f0a1}\u{1f0b1}\u{1f0d1}\u{1f0c1}][\u{1f0a5}\u{1f0b5}\u{1f0d5}\u{1f0c5}][\u{1f0a4}\u{1f0b4}\u{1f0d4}\u{1f0c4}][\u{1f0a3}\u{1f0b3}\u{1f0d3}\u{1f0c3}][\u{1f0a2}\u{1f0b2}\u{1f0d2}\u{1f0c2}]", "u");
+
+Hand.OfAKindRegExp = new RegExp("(?:[\u{1f0a1}\u{1f0b1}\u{1f0d1}\u{1f0c1}]{2,4})|(?:[\u{1f0ae}\u{1f0be}\u{1f0de}\u{1f0ce}]{2,4})|(?:[\u{1f0ad}\u{1f0bd}\u{1f0dd}\u{1f0cd}]{2,4})|(?:[\u{1f0ab}\u{1f0bb}\u{1f0db}\u{1f0cb}]{2,4})|(?:[\u{1f0aa}\u{1f0ba}\u{1f0da}\u{1f0ca}]{2,4})|(?:[\u{1f0a9}\u{1f0b9}\u{1f0d9}\u{1f0c9}]{2,4})|(?:[\u{1f0a8}\u{1f0b8}\u{1f0d8}\u{1f0c8}]{2,4})|(?:[\u{1f0a7}\u{1f0b7}\u{1f0d7}\u{1f0c7}]{2,4})|(?:[\u{1f0a6}\u{1f0b6}\u{1f0d6}\u{1f0c6}]{2,4})|(?:[\u{1f0a5}\u{1f0b5}\u{1f0d5}\u{1f0c5}]{2,4})|(?:[\u{1f0a4}\u{1f0b4}\u{1f0d4}\u{1f0c4}]{2,4})|(?:[\u{1f0a3}\u{1f0b3}\u{1f0d3}\u{1f0c3}]{2,4})|(?:[\u{1f0a2}\u{1f0b2}\u{1f0d2}\u{1f0c2}]{2,4})", "u");
+
+Hand.RoyalFlush = 0x900000;
+Hand.StraightFlush = 0x800000;
+Hand.FourOfAKind = 0x700000;
+Hand.FullHouse = 0x600000;
+Hand.Flush = 0x500000;
+Hand.Straight = 0x400000;
+Hand.ThreeOfAKind = 0x300000;
+Hand.TwoPair = 0x200000;
+Hand.Pair = 0x100000;
+
+class Player extends Hand
+{
+    constructor(name)
+    {
+        super();
+        this._name = name;
+        this._wins = 0;
+        this._handTypeCounts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+    }
+
+    scoreHand()
+    {
+        this.score();
+        let handType = this.rank >> 20;
+        this._handTypeCounts[handType]++;
+    }
+
+    wonHand()
+    {
+        this._wins++
+    }
+
+    get name()
+    {
+        return this._name;
+    }
+
+    get hand()
+    {
+        return super.toString();
+    }
+
+    get wins()
+    {
+        return this._wins;
+    }
+
+    get handTypeCounts()
+    {
+        return this._handTypeCounts;
+    }
+}
+
+function playHands(players)
+{
+    let cardDeck = new CardDeck();
+    let handsPlayed = 0;
+    let highestRank = 0;
+
+    do {
+        cardDeck.shuffle();
+
+        for (let player of players)
+            player.clear();
+
+        for (let i = 0; i < 5; i++) {
+            for (let player of players)
+                player.takeCard(cardDeck.dealOneCard());
+        }
+
+        for (let player of players)
+            player.scoreHand();
+
+        handsPlayed++;
+
+        highestRank = 0;
+
+        for (let player of players) {
+            if (player.rank > highestRank)
+                highestRank = player.rank;
+        }
+
+        for (let player of players) {
+            // We count ties as wins for each player.
+            if (player.rank == highestRank)
+                player.wonHand();
+        }
+    } while (handsPlayed < 2000);
+}

Modified: trunk/PerformanceTests/RexBench/about.html (220892 => 220893)


--- trunk/PerformanceTests/RexBench/about.html	2017-08-18 00:54:17 UTC (rev 220892)
+++ trunk/PerformanceTests/RexBench/about.html	2017-08-18 00:56:59 UTC (rev 220893)
@@ -24,6 +24,8 @@
 
         <p>Offline Assembler is the lexer, parser and AST layer of the offline assembler for _javascript_Core.  It has been ported to _javascript_ from the original Ruby.</p>
 
+        <p>UniPoker is a 5 card stud poker simulation using the Unicode playing cards code points, U+1F0A1..U+1F0DE, as the card representation in the code.  Scoring of hands is done with three regular expressions, one to check for a flush, one to check for straights, and one to check for pairs, three of a kind and four of a kind.  The last regular _expression_ is used twice as needed to find hands with 2 pairs or a full house.
+
         <p>Flight Planner is a newly written benchmark taken from a flight management web application.  Flight Planner parses aircraft flight plans and computes distance, course and elapsed times for legs of flight plans as well as total time.  It uses FAA data for airports, navigation aids and airways.  The flight management app was originally written to help compete in a flying proficiency event.  See <a href="" Air Rally</a>.
         </p>
 

Modified: trunk/PerformanceTests/RexBench/cli.js (220892 => 220893)


--- trunk/PerformanceTests/RexBench/cli.js	2017-08-18 00:54:17 UTC (rev 220892)
+++ trunk/PerformanceTests/RexBench/cli.js	2017-08-18 00:56:59 UTC (rev 220893)
@@ -53,6 +53,7 @@
 load("octane2_benchmark.js");
 load("basic_benchmark.js");
 load("offline_assembler_benchmark.js");
+load("unipoker_benchmark.js");
 load("flightplan_benchmark.js");
 load("flightplan_unicode_benchmark.js");
 load("glue.js");

Modified: trunk/PerformanceTests/RexBench/glue.js (220892 => 220893)


--- trunk/PerformanceTests/RexBench/glue.js	2017-08-18 00:54:17 UTC (rev 220892)
+++ trunk/PerformanceTests/RexBench/glue.js	2017-08-18 00:56:59 UTC (rev 220893)
@@ -39,7 +39,7 @@
 }
 
 {
-    const title = "RexBench 0.92";
+    const title = "RexBench 0.93";
     if (isInBrowser) {
         document.title = title;
     } else {
@@ -51,6 +51,7 @@
 driver.addBenchmark(Octane2RegExpBenchmarkRunner);
 driver.addBenchmark(BasicBenchmarkRunner);
 driver.addBenchmark(OfflineAssemblerBenchmarkRunner);
+driver.addBenchmark(UniPokerBenchmarkRunner);
 driver.addBenchmark(FlightPlannerBenchmarkRunner);
 driver.addBenchmark(FlightPlannerUnicodeBenchmarkRunner);
 driver.readyTrigger();

Modified: trunk/PerformanceTests/RexBench/index.html (220892 => 220893)


--- trunk/PerformanceTests/RexBench/index.html	2017-08-18 00:54:17 UTC (rev 220892)
+++ trunk/PerformanceTests/RexBench/index.html	2017-08-18 00:56:59 UTC (rev 220893)
@@ -140,6 +140,31 @@
             </div>
         </div>
 
+        <div class="unipoker test">
+            <h2 id="UniPokerMessage">UniPoker</h2> 
+            
+            <div class="score">
+                <label>First Iteration</label>
+                <span id="UniPokerFirstIteration">
+                    <span class="value">0</span><span class="units">ms</span>                    
+                </span>
+            </div>
+ 
+            <div class="score">
+                <label>Worst 4 Iteratons</label>
+                <span id="UniPokerAverageWorstCase">
+                    <span class="value">0</span><span class="units">ms</span>                    
+                </span>
+            </div>
+
+            <div class="score">
+                <label>Average</label>
+                <span id="UniPokerSteadyState">
+                    <span class="value">0</span><span class="units">ms</span>                    
+                </span>
+            </div>
+        </div>
+
         <div class="flight planner test">
             <h2 id="FlightPlannerMessage">Flight Planner</h2> 
             
@@ -198,6 +223,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
     <script src=""
     <script src=""

Added: trunk/PerformanceTests/RexBench/unipoker_benchmark.js (0 => 220893)


--- trunk/PerformanceTests/RexBench/unipoker_benchmark.js	                        (rev 0)
+++ trunk/PerformanceTests/RexBench/unipoker_benchmark.js	2017-08-18 00:56:59 UTC (rev 220893)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+"use strict";
+
+const UniPokerBenchmarkCode = String.raw`
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+<script>
+"use strict";
+var results = [];
+var benchmark = new UniPokerBenchmark();
+var numIterations = 20;
+benchmark.runIterations(numIterations, results);
+reportResult(results);
+</script>`;
+
+
+let runUniPokerBenchmark = null;
+if (!isInBrowser) {
+    let sources = [
+        "benchmark.js"
+        , "UniPoker/poker.js"
+        , "UniPoker/expected.js"
+        , "UniPoker/benchmark.js"
+    ];
+
+    runUniPokerBenchmark = makeBenchmarkRunner(sources, "UniPokerBenchmark", 20);
+}
+
+const UniPokerBenchmarkRunner = {
+    name: "UniPoker",
+    code: UniPokerBenchmarkCode,
+    run: runUniPokerBenchmark,
+    cells: {}
+};
+
+if (isInBrowser) {
+    UniPokerBenchmarkRunner.cells = {
+        firstIteration: document.getElementById("UniPokerFirstIteration"),
+        averageWorstCase: document.getElementById("UniPokerAverageWorstCase"),
+        steadyState: document.getElementById("UniPokerSteadyState"),
+        message: document.getElementById("UniPokerMessage")
+    };
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to