|
1569 | 1569 | // lazy define for hi-res timers |
1570 | 1570 | clock = function(clone) { |
1571 | 1571 | var deferred; |
1572 | | - templateData.uid = uid + uidCounter++; |
1573 | 1572 |
|
1574 | 1573 | if (clone instanceof Deferred) { |
1575 | 1574 | deferred = clone; |
1576 | 1575 | clone = deferred.benchmark; |
1577 | 1576 | } |
1578 | 1577 | var bench = clone._original, |
1579 | | - fn = bench.fn, |
1580 | | - fnArg = deferred ? getFirstArgument(fn) || 'deferred' : '', |
1581 | | - stringable = isStringable(fn); |
1582 | | - |
1583 | | - _.extend(templateData, { |
1584 | | - 'setup': getSource(bench.setup, interpolate('m#.setup()')), |
1585 | | - 'fn': getSource(fn, interpolate('m#.fn(' + fnArg + ')')), |
1586 | | - 'fnArg': fnArg, |
1587 | | - 'teardown': getSource(bench.teardown, interpolate('m#.teardown()')) |
1588 | | - }); |
1589 | | - |
1590 | | - // use API of chosen timer |
1591 | | - if (timer.unit == 'ns') { |
1592 | | - if (timer.ns.nanoTime) { |
1593 | | - _.extend(templateData, { |
1594 | | - 'begin': interpolate('s#=n#.nanoTime()'), |
1595 | | - 'end': interpolate('r#=(n#.nanoTime()-s#)/1e9') |
1596 | | - }); |
1597 | | - } else { |
1598 | | - _.extend(templateData, { |
1599 | | - 'begin': interpolate('s#=n#()'), |
1600 | | - 'end': interpolate('r#=n#(s#);r#=r#[0]+(r#[1]/1e9)') |
1601 | | - }); |
1602 | | - } |
1603 | | - } |
1604 | | - else if (timer.unit == 'us') { |
1605 | | - if (timer.ns.stop) { |
1606 | | - _.extend(templateData, { |
1607 | | - 'begin': interpolate('s#=n#.start()'), |
1608 | | - 'end': interpolate('r#=n#.microseconds()/1e6') |
1609 | | - }); |
1610 | | - } else if (perfName) { |
1611 | | - _.extend(templateData, { |
1612 | | - 'begin': interpolate('s#=n#.' + perfName + '()'), |
1613 | | - 'end': interpolate('r#=(n#.' + perfName + '()-s#)/1e3') |
1614 | | - }); |
1615 | | - } else { |
1616 | | - _.extend(templateData, { |
1617 | | - 'begin': interpolate('s#=n#()'), |
1618 | | - 'end': interpolate('r#=(n#()-s#)/1e6') |
1619 | | - }); |
1620 | | - } |
1621 | | - } |
1622 | | - else { |
1623 | | - _.extend(templateData, { |
1624 | | - 'begin': interpolate('s#=new n#'), |
1625 | | - 'end': interpolate('r#=(new n#-s#)/1e3') |
1626 | | - }); |
1627 | | - } |
1628 | | - |
1629 | | - var count = bench.count = clone.count, |
| 1578 | + stringable = isStringable(bench.fn), |
| 1579 | + count = bench.count = clone.count, |
1630 | 1580 | decompilable = support.decompilation || stringable, |
1631 | 1581 | id = bench.id, |
1632 | | - isEmpty = !(templateData.fn || stringable), |
1633 | 1582 | name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id), |
1634 | | - ns = timer.ns, |
1635 | 1583 | result = 0; |
1636 | 1584 |
|
1637 | 1585 | // init `minTime` if needed |
|
1641 | 1589 | // (some Chrome builds erase the `ns` variable after millions of executions) |
1642 | 1590 | if (applet) { |
1643 | 1591 | try { |
1644 | | - ns.nanoTime(); |
| 1592 | + timer.ns.nanoTime(); |
1645 | 1593 | } catch(e) { |
1646 | 1594 | // use non-element to avoid issues with libs that augment them |
1647 | | - ns = timer.ns = new applet.Packages.nano; |
| 1595 | + timer.ns = new applet.Packages.nano; |
1648 | 1596 | } |
1649 | 1597 | } |
1650 | | - // define `timer` methods |
1651 | | - timer.start = createFunction( |
1652 | | - interpolate('o#'), |
1653 | | - interpolate('var n#=this.ns,${begin};o#.elapsed=0;o#.timeStamp=s#') |
1654 | | - ); |
1655 | | - |
1656 | | - timer.stop = createFunction( |
1657 | | - interpolate('o#'), |
1658 | | - interpolate('var n#=this.ns,s#=o#.timeStamp,${end};o#.elapsed=r#') |
1659 | | - ); |
1660 | 1598 |
|
1661 | 1599 | // Compile in setup/teardown functions and the test loop. |
1662 | 1600 | // Create a new compiled test, instead of using the cached `bench.compiled`, |
|
1679 | 1617 | : 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count,n#=t#.ns;${setup}\n${begin};' + |
1680 | 1618 | 'while(i#--){${fn}\n}${end};${teardown}\nreturn{elapsed:r#,uid:"${uid}"}'; |
1681 | 1619 |
|
1682 | | - var compiled = bench.compiled = clone.compiled = createCompiled(funcBody); |
| 1620 | + var compiled = bench.compiled = clone.compiled = createCompiled(bench, deferred, funcBody), |
| 1621 | + isEmpty = !(templateData.fn || stringable); |
1683 | 1622 |
|
1684 | 1623 | try { |
1685 | 1624 | if (isEmpty) { |
|
1709 | 1648 | ',n#=t#.ns;${setup}\n${begin};m#.f#=f#;while(i#--){m#.f#()}${end};' + |
1710 | 1649 | 'delete m#.f#;${teardown}\nreturn{elapsed:r#}'; |
1711 | 1650 |
|
1712 | | - compiled = createCompiled(funcBody); |
| 1651 | + compiled = createCompiled(bench, deferred, funcBody); |
1713 | 1652 |
|
1714 | 1653 | try { |
1715 | 1654 | // pretest one more time to check for errors |
|
1725 | 1664 | } |
1726 | 1665 | } |
1727 | 1666 | } |
1728 | | - |
1729 | 1667 | // if no errors run the full test loop |
1730 | 1668 | if (!clone.error) { |
1731 | | - compiled = bench.compiled = clone.compiled = createCompiled(funcBody); |
| 1669 | + compiled = bench.compiled = clone.compiled = createCompiled(bench, deferred, funcBody); |
1732 | 1670 | result = compiled.call(deferred || bench, context, timer).elapsed; |
1733 | 1671 | } |
1734 | 1672 | return result; |
|
1739 | 1677 | /** |
1740 | 1678 | * Creates a compiled function from the given function `body`. |
1741 | 1679 | */ |
1742 | | - function createCompiled(body) { |
| 1680 | + function createCompiled(bench, deferred, body) { |
| 1681 | + var fn = bench.fn, |
| 1682 | + fnArg = deferred ? getFirstArgument(fn) || 'deferred' : ''; |
| 1683 | + |
| 1684 | + templateData.uid = uid + uidCounter++; |
| 1685 | + |
| 1686 | + _.extend(templateData, { |
| 1687 | + 'setup': getSource(bench.setup, interpolate('m#.setup()')), |
| 1688 | + 'fn': getSource(fn, interpolate('m#.fn(' + fnArg + ')')), |
| 1689 | + 'fnArg': fnArg, |
| 1690 | + 'teardown': getSource(bench.teardown, interpolate('m#.teardown()')) |
| 1691 | + }); |
| 1692 | + |
| 1693 | + // use API of chosen timer |
| 1694 | + if (timer.unit == 'ns') { |
| 1695 | + if (timer.ns.nanoTime) { |
| 1696 | + _.extend(templateData, { |
| 1697 | + 'begin': interpolate('s#=n#.nanoTime()'), |
| 1698 | + 'end': interpolate('r#=(n#.nanoTime()-s#)/1e9') |
| 1699 | + }); |
| 1700 | + } else { |
| 1701 | + _.extend(templateData, { |
| 1702 | + 'begin': interpolate('s#=n#()'), |
| 1703 | + 'end': interpolate('r#=n#(s#);r#=r#[0]+(r#[1]/1e9)') |
| 1704 | + }); |
| 1705 | + } |
| 1706 | + } |
| 1707 | + else if (timer.unit == 'us') { |
| 1708 | + if (timer.ns.stop) { |
| 1709 | + _.extend(templateData, { |
| 1710 | + 'begin': interpolate('s#=n#.start()'), |
| 1711 | + 'end': interpolate('r#=n#.microseconds()/1e6') |
| 1712 | + }); |
| 1713 | + } else if (perfName) { |
| 1714 | + _.extend(templateData, { |
| 1715 | + 'begin': interpolate('s#=n#.' + perfName + '()'), |
| 1716 | + 'end': interpolate('r#=(n#.' + perfName + '()-s#)/1e3') |
| 1717 | + }); |
| 1718 | + } else { |
| 1719 | + _.extend(templateData, { |
| 1720 | + 'begin': interpolate('s#=n#()'), |
| 1721 | + 'end': interpolate('r#=(n#()-s#)/1e6') |
| 1722 | + }); |
| 1723 | + } |
| 1724 | + } |
| 1725 | + else { |
| 1726 | + _.extend(templateData, { |
| 1727 | + 'begin': interpolate('s#=new n#'), |
| 1728 | + 'end': interpolate('r#=(new n#-s#)/1e3') |
| 1729 | + }); |
| 1730 | + } |
| 1731 | + // define `timer` methods |
| 1732 | + timer.start = createFunction( |
| 1733 | + interpolate('o#'), |
| 1734 | + interpolate('var n#=this.ns,${begin};o#.elapsed=0;o#.timeStamp=s#') |
| 1735 | + ); |
| 1736 | + |
| 1737 | + timer.stop = createFunction( |
| 1738 | + interpolate('o#'), |
| 1739 | + interpolate('var n#=this.ns,s#=o#.timeStamp,${end};o#.elapsed=r#') |
| 1740 | + ); |
| 1741 | + |
| 1742 | + // create compiled test |
1743 | 1743 | return createFunction( |
1744 | 1744 | interpolate('window,t#'), |
1745 | 1745 | 'var global = window, clearTimeout = global.clearTimeout, setTimeout = global.setTimeout;\n' + |
|
0 commit comments