[ 
https://issues.apache.org/jira/browse/MATH-1406?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15897042#comment-15897042
 ] 

Michael Borcherds edited comment on MATH-1406 at 3/6/17 10:23 AM:
------------------------------------------------------------------

{noformat}
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math3;

import java.util.Random;
import java.util.concurrent.Callable;

import org.apache.commons.math3.exception.MathIllegalStateException;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.stat.descriptive.StatisticalSummary;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.geogebra.common.main.App;
import org.geogebra.common.util.debug.Log;

/**
 * Simple benchmarking utilities.
 */
public class PerfTestUtils {
        /** Nanoseconds to milliseconds conversion factor ({@value}). */
        public static final double NANO_TO_MILLI = 1e-6;
        /** Default number of code repeat per timed block. */
        private static final int DEFAULT_REPEAT_CHUNK = 1000;
        /** Default number of code repeats for computing the average run time. 
*/
        private static final int DEFAULT_REPEAT_STAT = 10000;
        /** RNG. */
        private static Random rng = new Random();

        /**
         * Timing.
         *
         * @param repeatChunk
         *            Each timing measurement will done done for that number of
         *            repeats of the code.
         * @param repeatStat
         *            Timing will be averaged over that number of runs.
         * @param runGC
         *            Call {@code System.gc()} between each timed block. When 
set to
         *            {@code true}, the test will run much slower.
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods}, a
         *         {@link StatisticalSummary} of the average times (in 
milliseconds)
         *         taken by a single call to the {@code call} method (i.e. the 
time
         *         taken by each timed block divided by {@code repeatChunk}).
         */
        @SuppressWarnings("unchecked")
        public static StatisticalSummary[] time(App app, int repeatChunk,
                        int repeatStat,
                        boolean runGC, RunTest... methods) {
                final double[][][] times = timesAndResults(app, repeatChunk, 
repeatStat,
                                runGC, methods);

                final int len = methods.length;
                final StatisticalSummary[] stats = new StatisticalSummary[len];
                for (int j = 0; j < len; j++) {
                        final SummaryStatistics s = new SummaryStatistics();
                        for (int k = 0; k < repeatStat; k++) {
                                s.addValue(times[j][k][0]);
                        }
                        stats[j] = s.getSummary();
                }

                return stats;
        }

        /**
         * Timing.
         *
         * @param repeatChunk
         *            Each timing measurement will done done for that number of
         *            repeats of the code.
         * @param repeatStat
         *            Timing will be averaged over that number of runs.
         * @param runGC
         *            Call {@code System.gc()} between each timed block. When 
set to
         *            {@code true}, the test will run much slower.
         * @param methods
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods} (first dimension), and 
each
         *         of the {@code repeatStat} runs (second dimension):
         *         <ul>
         *         <li>the average time (in milliseconds) taken by a single 
call to
         *         the {@code call} method (i.e. the time taken by each timed 
block
         *         divided by {@code repeatChunk})</li>
         *         <li>the result returned by the {@code call} method.</li>
         *         </ul>
         */
        @SuppressWarnings("unchecked")
        public static double[][][] timesAndResults(App app, int repeatChunk,
                        int repeatStat,
                        boolean runGC, RunTest[] methods) {
                final int numMethods = methods.length;
                final double[][][] timesAndResults = new 
double[numMethods][repeatStat][2];

                try {
                        for (int k = 0; k < repeatStat; k++) {
                                for (int j = 0; j < numMethods; j++) {
                                        if (runGC) {
                                                // Try to perform GC outside 
the timed block.
                                                System.gc();
                                        }

                                        final RunTest r = methods[j];
                                        final double[] result = new 
double[repeatChunk];

                                        // Timed block.
                                        final long start = 
FastMathTestPerformance.nanoTime(app);
                                        for (int i = 0; i < repeatChunk; i++) {
                                                result[i] = 
r.call().doubleValue();
                                        }
                                        final long stop = 
FastMathTestPerformance.nanoTime(app);

                                        // Collect run time.
                                        timesAndResults[j][k][0] = (stop - 
start) * NANO_TO_MILLI;
                                        // Keep track of a randomly selected 
result.
                                        timesAndResults[j][k][1] = 
result[rng.nextInt(repeatChunk)];
                                }
                        }
                } catch (Exception e) {
                        // Abort benchmarking if codes throw exceptions.
                        throw new 
MathIllegalStateException(LocalizedFormats.SIMPLE_MESSAGE,
                                        e.getMessage());
                }

                final double normFactor = 1d / repeatChunk;
                for (int j = 0; j < numMethods; j++) {
                        for (int k = 0; k < repeatStat; k++) {
                                timesAndResults[j][k][0] *= normFactor;
                        }
                }

                return timesAndResults;
        }

        /**
         * Timing and report (to standard output) the average time and standard
         * deviation of a single call. The timing is performed by calling the
         * {@link #time(int,int,boolean,Callable[]) time} method.
         *
         * @param title
         *            Title of the test (for the report).
         * @param repeatChunk
         *            Each timing measurement will done done for that number of
         *            repeats of the code.
         * @param repeatStat
         *            Timing will be averaged over that number of runs.
         * @param runGC
         *            Call {@code System.gc()} between each timed block. When 
set to
         *            {@code true}, the test will run much slower.
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods}, a statistics of the
         *         average times (in milliseconds) taken by a single call to the
         *         {@code call} method (i.e. the time taken by each timed block
         *         divided by {@code repeatChunk}).
         */
        @SuppressWarnings("boxing")
        public static StatisticalSummary[] timeAndReport(App app, String title,
                        int repeatChunk, int repeatStat, boolean runGC,
                        RunTest... methods) {
                // Header format.
                final String hFormat = "%s (calls per timed block: %d, timed 
blocks: %d, time unit: ms)";

                // Width of the longest name.
                int nameLength = 0;
                for (RunTest m : methods) {
                        int len = m.getName().length();
                        if (len > nameLength) {
                                nameLength = len;
                        }
                }
                final String nameLengthFormat = "%" + nameLength + "s";

                // Column format.
                // final String cFormat = nameLengthFormat + " %14s %14s %10s 
%10s
                // %15s";
                // Result format.
                // final String format = nameLengthFormat + " %.8e %.8e %.4e 
%.4e %
                // .8e";

                Log.debug(
                                (hFormat + " " + title + " " + repeatChunk + " 
" + repeatStat));
                Log.debug((" " + "name" + " " + "time/call" + " "
                                + "std error" + " " + "total time" + " " + 
"ratio" + " "
                                + "difference"));
                final StatisticalSummary[] time = time(app, repeatChunk, 
repeatStat,
                                runGC,
                                methods);
                final double refSum = time[0].getSum() * repeatChunk;
                for (int i = 0, max = time.length; i < max; i++) {
                        final StatisticalSummary s = time[i];
                        final double sum = s.getSum() * repeatChunk;
                        Log.debug((" " + methods[i].getName() + " "
                                        + s.getMean() + " " + 
s.getStandardDeviation() + " " + sum
                                        + " " + sum / refSum + " " + (sum - 
refSum)));
                }

                return time;
        }

        /**
         * Timing and report (to standard output). This method calls
         * {@link #timeAndReport(String,int,int,boolean,RunTest[])
         * timeAndReport(title, 1000, 10000, false, methods)}.
         *
         * @param title
         *            Title of the test (for the report).
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods}, a statistics of the
         *         average times (in milliseconds) taken by a single call to the
         *         {@code call} method (i.e. the time taken by each timed block
         *         divided by {@code repeatChunk}).
         */
        public static StatisticalSummary[] timeAndReport(App app, String title,
                        RunTest... methods) {
                return timeAndReport(app, title, DEFAULT_REPEAT_CHUNK,
                                DEFAULT_REPEAT_STAT,
                                false, methods);
        }

        /**
         * Utility class for storing a test label.
         */
        public static abstract class RunTest {
                private final String name;

                /**
                 * @param name
                 *            Test name.
                 */
                public RunTest(String name) {
                        this.name = name;
                }

                /**
                 * @return the name of this test.
                 */
                public String getName() {
                        return name;
                }

                /** {@inheritDoc} */
                public abstract Double call() throws Exception;
        }
}
{noformat}


was (Author: murkle):
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math3;

import java.util.Random;
import java.util.concurrent.Callable;

import org.apache.commons.math3.exception.MathIllegalStateException;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.stat.descriptive.StatisticalSummary;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.geogebra.common.main.App;
import org.geogebra.common.util.debug.Log;

/**
 * Simple benchmarking utilities.
 */
public class PerfTestUtils {
        /** Nanoseconds to milliseconds conversion factor ({@value}). */
        public static final double NANO_TO_MILLI = 1e-6;
        /** Default number of code repeat per timed block. */
        private static final int DEFAULT_REPEAT_CHUNK = 1000;
        /** Default number of code repeats for computing the average run time. 
*/
        private static final int DEFAULT_REPEAT_STAT = 10000;
        /** RNG. */
        private static Random rng = new Random();

        /**
         * Timing.
         *
         * @param repeatChunk
         *            Each timing measurement will done done for that number of
         *            repeats of the code.
         * @param repeatStat
         *            Timing will be averaged over that number of runs.
         * @param runGC
         *            Call {@code System.gc()} between each timed block. When 
set to
         *            {@code true}, the test will run much slower.
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods}, a
         *         {@link StatisticalSummary} of the average times (in 
milliseconds)
         *         taken by a single call to the {@code call} method (i.e. the 
time
         *         taken by each timed block divided by {@code repeatChunk}).
         */
        @SuppressWarnings("unchecked")
        public static StatisticalSummary[] time(App app, int repeatChunk,
                        int repeatStat,
                        boolean runGC, RunTest... methods) {
                final double[][][] times = timesAndResults(app, repeatChunk, 
repeatStat,
                                runGC, methods);

                final int len = methods.length;
                final StatisticalSummary[] stats = new StatisticalSummary[len];
                for (int j = 0; j < len; j++) {
                        final SummaryStatistics s = new SummaryStatistics();
                        for (int k = 0; k < repeatStat; k++) {
                                s.addValue(times[j][k][0]);
                        }
                        stats[j] = s.getSummary();
                }

                return stats;
        }

        /**
         * Timing.
         *
         * @param repeatChunk
         *            Each timing measurement will done done for that number of
         *            repeats of the code.
         * @param repeatStat
         *            Timing will be averaged over that number of runs.
         * @param runGC
         *            Call {@code System.gc()} between each timed block. When 
set to
         *            {@code true}, the test will run much slower.
         * @param methods
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods} (first dimension), and 
each
         *         of the {@code repeatStat} runs (second dimension):
         *         <ul>
         *         <li>the average time (in milliseconds) taken by a single 
call to
         *         the {@code call} method (i.e. the time taken by each timed 
block
         *         divided by {@code repeatChunk})</li>
         *         <li>the result returned by the {@code call} method.</li>
         *         </ul>
         */
        @SuppressWarnings("unchecked")
        public static double[][][] timesAndResults(App app, int repeatChunk,
                        int repeatStat,
                        boolean runGC, RunTest[] methods) {
                final int numMethods = methods.length;
                final double[][][] timesAndResults = new 
double[numMethods][repeatStat][2];

                try {
                        for (int k = 0; k < repeatStat; k++) {
                                for (int j = 0; j < numMethods; j++) {
                                        if (runGC) {
                                                // Try to perform GC outside 
the timed block.
                                                System.gc();
                                        }

                                        final RunTest r = methods[j];
                                        final double[] result = new 
double[repeatChunk];

                                        // Timed block.
                                        final long start = 
FastMathTestPerformance.nanoTime(app);
                                        for (int i = 0; i < repeatChunk; i++) {
                                                result[i] = 
r.call().doubleValue();
                                        }
                                        final long stop = 
FastMathTestPerformance.nanoTime(app);

                                        // Collect run time.
                                        timesAndResults[j][k][0] = (stop - 
start) * NANO_TO_MILLI;
                                        // Keep track of a randomly selected 
result.
                                        timesAndResults[j][k][1] = 
result[rng.nextInt(repeatChunk)];
                                }
                        }
                } catch (Exception e) {
                        // Abort benchmarking if codes throw exceptions.
                        throw new 
MathIllegalStateException(LocalizedFormats.SIMPLE_MESSAGE,
                                        e.getMessage());
                }

                final double normFactor = 1d / repeatChunk;
                for (int j = 0; j < numMethods; j++) {
                        for (int k = 0; k < repeatStat; k++) {
                                timesAndResults[j][k][0] *= normFactor;
                        }
                }

                return timesAndResults;
        }

        /**
         * Timing and report (to standard output) the average time and standard
         * deviation of a single call. The timing is performed by calling the
         * {@link #time(int,int,boolean,Callable[]) time} method.
         *
         * @param title
         *            Title of the test (for the report).
         * @param repeatChunk
         *            Each timing measurement will done done for that number of
         *            repeats of the code.
         * @param repeatStat
         *            Timing will be averaged over that number of runs.
         * @param runGC
         *            Call {@code System.gc()} between each timed block. When 
set to
         *            {@code true}, the test will run much slower.
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods}, a statistics of the
         *         average times (in milliseconds) taken by a single call to the
         *         {@code call} method (i.e. the time taken by each timed block
         *         divided by {@code repeatChunk}).
         */
        @SuppressWarnings("boxing")
        public static StatisticalSummary[] timeAndReport(App app, String title,
                        int repeatChunk, int repeatStat, boolean runGC,
                        RunTest... methods) {
                // Header format.
                final String hFormat = "%s (calls per timed block: %d, timed 
blocks: %d, time unit: ms)";

                // Width of the longest name.
                int nameLength = 0;
                for (RunTest m : methods) {
                        int len = m.getName().length();
                        if (len > nameLength) {
                                nameLength = len;
                        }
                }
                final String nameLengthFormat = "%" + nameLength + "s";

                // Column format.
                // final String cFormat = nameLengthFormat + " %14s %14s %10s 
%10s
                // %15s";
                // Result format.
                // final String format = nameLengthFormat + " %.8e %.8e %.4e 
%.4e %
                // .8e";

                Log.debug(
                                (hFormat + " " + title + " " + repeatChunk + " 
" + repeatStat));
                Log.debug((" " + "name" + " " + "time/call" + " "
                                + "std error" + " " + "total time" + " " + 
"ratio" + " "
                                + "difference"));
                final StatisticalSummary[] time = time(app, repeatChunk, 
repeatStat,
                                runGC,
                                methods);
                final double refSum = time[0].getSum() * repeatChunk;
                for (int i = 0, max = time.length; i < max; i++) {
                        final StatisticalSummary s = time[i];
                        final double sum = s.getSum() * repeatChunk;
                        Log.debug((" " + methods[i].getName() + " "
                                        + s.getMean() + " " + 
s.getStandardDeviation() + " " + sum
                                        + " " + sum / refSum + " " + (sum - 
refSum)));
                }

                return time;
        }

        /**
         * Timing and report (to standard output). This method calls
         * {@link #timeAndReport(String,int,int,boolean,RunTest[])
         * timeAndReport(title, 1000, 10000, false, methods)}.
         *
         * @param title
         *            Title of the test (for the report).
         * @param methods
         *            Codes being timed.
         * @return for each of the given {@code methods}, a statistics of the
         *         average times (in milliseconds) taken by a single call to the
         *         {@code call} method (i.e. the time taken by each timed block
         *         divided by {@code repeatChunk}).
         */
        public static StatisticalSummary[] timeAndReport(App app, String title,
                        RunTest... methods) {
                return timeAndReport(app, title, DEFAULT_REPEAT_CHUNK,
                                DEFAULT_REPEAT_STAT,
                                false, methods);
        }

        /**
         * Utility class for storing a test label.
         */
        public static abstract class RunTest {
                private final String name;

                /**
                 * @param name
                 *            Test name.
                 */
                public RunTest(String name) {
                        this.name = name;
                }

                /**
                 * @return the name of this test.
                 */
                public String getName() {
                        return name;
                }

                /** {@inheritDoc} */
                public abstract Double call() throws Exception;
        }
}


> official support for compiling on GWT 2.8
> -----------------------------------------
>
>                 Key: MATH-1406
>                 URL: https://issues.apache.org/jira/browse/MATH-1406
>             Project: Commons Math
>          Issue Type: Improvement
>            Reporter: Michael Borcherds
>   Original Estimate: 168h
>  Remaining Estimate: 168h
>
> Is there any interest in allowing Apache Commons Math to be officially 
> supported on GWT?
> With GWT 2.8.0 the changes needed aren't too hard to get most of it to compile
> You can see the diff from 3.6.1 here:
> https://github.com/murkle/commons-math/issues/1



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to