I have an exercise that I am working on for programming class. I am getting an odd error that seems very basic, yet I am having trouble debugging it.
The code, when referenced, creates the standard StopWatch object with several instance methods associated with it. I created a main method at the bottom of the code in order to test each method in the StopWatch class to make sure it is working correctly.
Currently, when I run the program I get an error that says:
Exception in thread "main" java.lang.NoSuchMethodError: main.
I clearly have a main method in this class so I am not sure why I am getting this error.
The main method implements the Gambler's ruin program for testing. I am currently trying to test the stop() and elapsedTime() methods. The full code is enclosed below:
/* Notes:
* Start is the date of birth of the object. Most stopwatch don't keep track of when they were
* created.
*/
public class Stopwatch {
public long startTime; //The creation time of the stopwatch
public long totalTime; //Total time since watch was zeroed
boolean running = false; //This will flag if the watch is started or stopped
public Stopwatch() //First instance method called Stopwatch. What the client will use to create Stopwatch. This serves as the constructor.
{
start();
}
public void start()
{
startTime = System.currentTimeMillis();
running = true;
}
public void stop()
{
if(running) {
totalTime += System.currentTimeMillis() - startTime;
running = false;
}
}
public double elapsedTime()
{
if(running){
return System.currentTimeMillis() - startTime;
}
else{
return 0; //If the watch isn't currently running, return a 0 value.
}
}
public void zero()
{
totalTime = 0;
start();
}
public static void main(String[] args)
{
// Run T experiments that start with $stake and terminate on $0 or $goal.
Stopwatch program_time = new Stopwatch();
int stake = Integer.parseInt(args[0]);
int goal = Integer.parseInt(args[1]);
int T = Integer.parseInt(args[2]);
int bets = 0;
int wins = 0;
for (int t = 0; t < T; t++)
{
// Run one experiment
int cash = stake;
while (cash > 0 && cash < goal)
{
// Simulate one bet.
bets = bets + 1;
if (Math.random() < 0.5)
{
cash = cash + 1;
}
else
{
cash = cash - 1;
}
} // Cash is either going to be at $0 (ruin) or $goal (win)
if (cash == goal)
{
wins = wins + 1;
}
}
System.out.println(100 * wins / T + "% wins");
System.out.println("Avg # bets: " + bets/T);
program_time.stop();
System.out.println(program_time.elapsedTime());
}
}
Any thoughts?
Check the file and class names -- they must match exactly, even with upper and lower case.
Check whether the Classpath is correct or not.
Related
Okay so I am trying to add methods this stopwatch class to pause and resume the time on the stopwatch. The stopwatch works fine and so does the resume method. The problem is with the pause method.
When I use elapsedTime to check how much time has passed and then the pause method to pause the time and then I wait for a little bit and check the time again, the time paused. However if I then wait for a little bit and check the time again by using elapsedTime (without using pause() again) the time changes as if I had resume the time. If I check time, pause, check time, pause,... then the time does not change but obviously I want the time to stay paused until I resume.
public class Stopwatch {
private final long start;
private long additionalTime;
private long pauseStart;
public Stopwatch() {
start = System.currentTimeMillis();}
public void pause() {
if (pauseStart == 0)
pauseStart = System.currentTimeMillis();
}
public void resume() {
if (pauseStart != 0) {
long stopTime = System.currentTimeMillis() - pauseStart;
additionalTime += stopTime;
pauseStart = 0;
}
}
public double elapsedTime() {
long now = System.currentTimeMillis();
if (pauseStart != 0) {
long stopTime = System.currentTimeMillis() - pauseStart;
additionalTime += stopTime;
pauseStart = 0;
}
return ((now - start) - additionalTime) / 1000.0;}
public static void main(String[] args) {
Stopwatch watch = new Stopwatch();
double total = 0.0;
for (int i = 0; i < 100000000; i++)
total += Math.random();
double time = watch.elapsedTime();
StdOut.println(timi);
watch.pause();
for (int i = 0; i < 200000000; i++)
total += Math.random();
time = watch.elapsedTime();
StdOut.println(time);
for (int i = 0; i < 200000000; i++)
total += Math.random();
time = watch.elapsedTime();
StdOut.println(time);
}
}
I think you should use two different classes. Have you considered something like this?
Rename your Stopwatch class to, let's say: InnerStopwatch.
Create a new Stopwatch class that holds a List of InnerStopwatchs.
When you start a Stopwatch, it creates a new InnerStopwatch, starts it and stores a reference to it as your "current inner stopwatch"
When you pause the Stopwatch, it calls the stop method on the "current inner stopwatch".
When you resume the Stopwatch, it creates a new InnerStopwatch and starts it; and marks it as the new "current inner stopwatch"
When you ask for the elapsed time, than it sums the elapsed times of all inner stopwatchs in the List.
Please let me know if that works for you.
This question already has answers here:
How do I write a correct micro-benchmark in Java?
(11 answers)
Closed 4 years ago.
please i need help i am writing this code to be able to display my execution time anytime i run a program but i usually get different time even when its the same input
after importing all this
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/** Class KnuthMorrisPratt **/
public class Knuth1
{
/** Failure array **/
private int[] failure;
/** Constructor **/
public Knuth1(String text, String pat)
{
/** pre construct failure array for a pattern **/
failure = new int[pat.length()];
fail(pat);
/** find match **/
int pos = posMatch(text, pat);
if (pos == -1)
System.out.println("\nNo match found");
else
System.out.println("\nMatch found at index "+ pos);
}
/** Failure function for a pattern **/
private void fail(String pat)
{
int n = pat.length();
failure[0] = -1;
for (int j = 1; j < n; j++)
{
int i = failure[j - 1];
while ((pat.charAt(j) != pat.charAt(i + 1)) && i >= 0)
i = failure[i];
if (pat.charAt(j) == pat.charAt(i + 1))
failure[j] = i + 1;
else
failure[j] = -1;
}
}
/** Function to find match for a pattern **/
private int posMatch(String text, String pat)
{
int i = 0, j = 0;
int lens = text.length();
int lenp = pat.length();
while (i < lens && j < lenp)
{
if (text.charAt(i) == pat.charAt(j))
{
i++;
j++;
}
else if (j == 0)
i++;
else
j = failure[j - 1] + 1;
}
return ((j == lenp) ? (i - lenp) : -1);
}
/** Main Function **/
public static void main(String[] args) throws IOException
{
//i think its here were i get the input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in) ));
System.out.println("Knuth Morris Pratt Test\n");
System.out.println("\nEnter Text: ");
String text = br.readLine();
System.out.print("\nEnter Pattern");
String pattern = br.readLine();
double starttime = System.nanoTime();
Knuth1 kmp = new Knuth1(text, pattern);
double endtime = System.nanoTime();
double executiontime = (endtime - starttime )/1000000000;
// System.out.printf("%.4f","Execution Time = "+ executiontime + " Seconds");
System.out.print("Execution Time = ");
System.out.format("%.4f", executiontime);
System.out.print(" Seconds");
// System.out.println(starttime);
// System.out.println(endtime);
//I love programming with JAVA and Php. It’s fun and interesting.
}
}
this code will check an input strings and pick out the unique word and the try to also display the execution time for the program... what i really want now is to make sure the execution time remain the same when i input the same input.
If you don't care about reusing the timed functionality, use System.nanoTime()
long before;
long after;
// Get time before
before = System.nanoTime();
// Code you want to execute here
// Get time after
after = System.nanoTime();
// Calculate duration
long diff = after - before;
You can encapsulate any code you want into a Runnable or using any of Java 8's new Predicate or Function interfaces which are very similar. You can put the code that you want to run in a lambda expression (like an anonymous function) and pass it to a static method that calculates in nanoseconds the amount of time it takes the runnable object to execute.
This is more code than what is necessary, but it reusable in that you don't have to keep writing start = System.currentTimeMillis() or System.nanoTime()and doing arithmetic every time you want to time something. You can put this function in your static library and use it whenever you want.
/**
* Times a runnable. Note, there
* is probably overhead associated with
* creating a Runnable object, but if
* assume that's constant for all Runnable
* objects, then we can simply ignore it
*
* #param runnable Runnable to run
* #return Number of nanoseconds it took to run the Runnable
*/
public static long timedAction(Runnable runnable) {
long before;
long after;
before = System.nanoTime();
runnable.run();
after = System.nanoTime();
return after - before;
}
This is how I use this code block:
public static void main(String[] args) throws Exception {
final int numKeys = 1000000;
// Builds an AVL tree
Runnable snippet = () -> {
Tree<Integer, Object> avl = new AVLTree<>();
for (int i = 0; i < numKeys; i++) {
avl.insert(i, i);
}
};
long nanoSecond = Util.timedAction(snippet);
double seconds = Mathematics.nanosecondsToSeconds(nanoSecond);
System.out.println(seconds);
}
Output:
0.493316448
I have a Runnable "NanoClock" class which keeps updating a private volatile double value in its run() method.
This class also has a getTime() method which returns the double value. Another class ("Master") is constructing the NanoClock class and creates a thread, as well as calling the start() method.
After it did this it calls the getTime() method several times (with a delay), but the value is not updating. What am I doing wrong?
NanoClock.java :
public class NanoClock implements Runnable {
private volatile boolean running;
private volatile double time;
public NanoClock() {
time = System.currentTimeMillis();
}
#Override
public void run() {
running = true;
while(running) {
try {
if(System.currentTimeMillis() > time) {
time = System.currentTimeMillis();
}
//This returns the updated value continuously when commented out
//System.out.println("Time: " + String.format("%.6f", unix_time));
Thread.sleep(2000);
} catch(Exception exc) {
exc.printStackTrace();
System.exit(1);
}
}
}
public double getTime() {
return time;
}
public void end() {
running = false;
}
}
Master.java:
public class Master {
public static void main(String[] args) {
try {
NanoClock nClock = new NanoClock();
Thread clockThread = new Thread(new NanoClock());
clockThread.setPriority(10);
clockThread.start();
//MY_ISSUE: This returns the same value every time
for(int a = 0; a < 10; a++) {
System.out.println("Time: " + nClock.getTime());
}
//MY_ISSUE: This cannot stop the while loop - I tested it with
//the println in the NanoClock class.
nClock.end();
System.out.println("Done!");
catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
You've got two instances of NanoClock: one of them is an anonymous new NanoClock() which, as the Runnable in your other thread is happily keeping time in the backgound; the other is nClock, which is sitting idly by in the foreground in your main thread.
nClock should have been the Runnable in that other thread:
Thread clockThread = new Thread(nClock); // not new NanoClock()
This may not be the entire solution, but it should be a big step in the right direction.
System.currentTimeMillis() returns a long, but you store it in a double, which causes a loss of precision. When you change the member time (and also the return type of its getter) to a long you should get the expected result.
As a rule of thumb: When working with time units long is most appropriate datatype most of the time. Floating point numbers are not suitable to store precise results.
Thread.sleep(2000);
System.out.println("Time: " + nClock.getTime());
the for in main() must be sleep(2000)
If the code below will take 2 seconds, then the time will change.
//MY_ISSUE: This returns the same value every time
for(int a = 0; a < 10; a++) {
System.out.println("Time: " + nClock.getTime());
}
However a for loop with 10 iterations and a system.out will not even take a millisecond so it will not change.
Why 2 seconds? because you have a Thread.sleep in your runnable code.
Thread.sleep(2000);
Which means, the next update will be in 2 seconds.
And use System.nanoTime() instead of System.currentTimeMillis() since you really wanted nano time not millis.
Updated:
In my machine
public static void main(String args[]) {
long start = System.currentTimeMillis();
for(int a = 0; a < 10; a++) {
System.out.println("Iterating " + a);
}
long end = System.currentTimeMillis();
System.out.println("Start = " + start);
System.out.println("End = " + end);
}
Result, there is no difference in the start time and end time
Iterating 0
Iterating 1
Iterating 2
Iterating 3
Iterating 4
Iterating 5
Iterating 6
Iterating 7
Iterating 8
Iterating 9
Start = 1499592836298
End = 1499592836298
That code block executed so fast that it did not take even a single millisecond. Depending on the timing, it may take 1 millisecond.
Changing it to System.nanoTime()
public static void main(String args[]) {
long start = System.nanoTime();
for(int a = 0; a < 10; a++) {
System.out.println("Iterating " + a);
}
long end = System.nanoTime();
System.out.println("Start = " + start);
System.out.println("End = " + end);
}
Result, there is a difference in the start time and end time.
Iterating 0
Iterating 1
Iterating 2
Iterating 3
Iterating 4
Iterating 5
Iterating 6
Iterating 7
Iterating 8
Iterating 9
Start = 1012518090518837
End = 1012518091012960
Have an issue where the performance of a simple loop (see code below in LoopTest.performTest) varies dramatically, but is consistent for the lifetime of the process.
For example, when run from within Weblogic/Tomcat it may achieve an average of 3.5 billion iterations per second. Re-start and it may only achieve 20 million iterations per second. This will remain consistent for the lifetime of the process. When it has been run directly from the command line, on every occasion, it has run fast.
This has been run under linux, windows, Tomcat & WebLogic. The slow execution occurs more regularly in WebLogic than Tomcat.
Test Specifics
The test code moves any potential OS calls (timing) to before and after the test, with differing size loops which should allow any slow OS calls to be apparent as a progressive apparent performance improvement as loop size increases.
The number of iterations performed by the test is determined by time (see runTest) rather than being fixed due to large variation in performance and is thus more complex than may initially be expected.
public static abstract class PerformanceTest {
private final String name;
public PerformanceTest(String name) {
this.name = name;
}
/**
* Return value to ensure loops etc not optimised away.
*
* #param loopCount
* #return
*/
public abstract long performTest(final long loopCount);
public String getName() {
return name;
}
}
private static class LoopTest extends PerformanceTest {
LoopTest() {
super("Loop");
}
#Override
public long performTest(final long loopCount) {
long sum=0;
for(long i=0;i<loopCount;i++) {
sum+=i;
}
return sum;
}
}
public static List<PerformanceTest> loadTests() {
List<PerformanceTest> performanceTests = new ArrayList<PerformanceTest>();
performanceTests.add(new LoopTest());
return performanceTests;
}
public static void main(String[] argv) {
int maxDuration = 30;
if (argv.length == 1) {
maxDuration = Integer.parseInt(argv[0]);
}
List<PerformanceTest> tests = loadTests();
for(PerformanceTest test : tests) {
runTest(test, maxDuration);
}
}
public static void runTest(PerformanceTest test, int maxDuration) {
System.out.println("Processing " + test.getName());
long stopDuration = 1000 * maxDuration;
long estimatedDuration = 1;
long priorDelta = 1;
long loopCount=10;
while (estimatedDuration < stopDuration) {
long startTime = System.currentTimeMillis();
test.performTest(loopCount);
long endTime = System.currentTimeMillis();
long delta = endTime - startTime;
estimatedDuration = delta * Math.max(10, delta / Math.min(estimatedDuration, priorDelta));
if (estimatedDuration <= 0) {
estimatedDuration = 1;
}
priorDelta = delta;
if (priorDelta <= 0) {
priorDelta = 1;
}
if (delta > 0) {
double itemsPerSecond = 1000 * (double)loopCount / (double)delta;
DecimalFormat formatter;
if (itemsPerSecond < 1) {
formatter = new DecimalFormat( "#,###,###,##0.000");
} else if (itemsPerSecond < 10) {
formatter = new DecimalFormat( "#,###,###,##0.0");
} else {
formatter = new DecimalFormat( "#,###,###,##0");
}
System.out.println(" " + loopCount + " : Duration " + delta + ", Items Per-Second: " + formatter.format(itemsPerSecond));
}
loopCount*=10;
}
}
I can't figure out why eclipse wants me to delete the ";" and replace it with with a ",".
numberOfTimes1 = numberOfTimes + numberOfDelayTimes;
I'm guessing it's some simple syntax thing that I forgot about. Could you please explain why it's doing that and also how to fix it.
Entire Program
public class Spam {
public static void main(String[] args) {
//1- Taking an instance of Timer class.
Timer timer = new Timer("Printer");
//2- Taking an instance of class contains your repeated method.
timeso t = new timeso();
timer.schedule(t, 0, 10);
}
}
class timeso extends TimerTask {
//times member represent calling times.
private int times = 0;
int time = 6; //How long do you wish for the spamming to run?
int numberOfTimes = time * 100;
int delayTime = 5; //How long do you wish for the program to wait before spamming?
int numberOfDelayTimes = delayTime * 100;
numberOfTimes = numberOfTimes + numberOfDelayTimes;
String spam;
Random randomGenerator = new Random();
public void run() {
times++;
if (times >= numberOfDelayTimes && times <= numberOfTimes+numberOfDelayTimes) {
try {
Robot typer = new Robot();
//for(int x = 1;x <=randomGenerator.nextInt(5); x++){
// spam = spam + randomGenerator.nextInt(10);
//}
byte[] bytes = "spam".getBytes();
//byte[] bytes = spam.getBytes();
for (byte b : bytes){
int code = b;
// key code only handles [A-Z] (which is ASCII decimal [65-90])
if (code > 96 && code < 123) code = code - 32;
typer.delay(10/bytes.length+1);
typer.keyPress(code);
typer.keyRelease(code);
}
if(times % (randomGenerator.nextInt(25)+1) == 0){
typer.delay(10/bytes.length+1);
typer.keyPress(KeyEvent.VK_ENTER);
typer.keyRelease(KeyEvent.VK_ENTER);
}
}
catch (AWTException e){
}
} else {
if (times >= numberOfTimes){
try{
Robot typer = new Robot();
typer.delay(10);
typer.keyPress(KeyEvent.VK_ENTER);
typer.keyRelease(KeyEvent.VK_ENTER);
} catch(Exception e){
}
//Stop Timer.
this.cancel();
}
}
}
}
You're trying to call a line of code outside of a method or constructor, and this is why the Java compiler (not Eclipse) is complaining. Do that sort of code in the constructor or method, not naked in the class. In fact all that code in your timeso class is incorrect and needs to be in a method or constructor.
Note: you'll want to learn Java naming convention and stick with it, including starting class names with an upper-case letter and method and variable names with a lower-case letter. Doing this will help others (us!) understand your code better.