Wait a minute – in less than ten seconds

71

4

Task

Using any type of parallelisation, wait multiple periods, for a total sleep time of at least a minute (but less than a minute and a half).

The program/function must terminate within 10 seconds and return (by any means and in any format) two values: the total elapsed time, and the total executed sleep time. Both time values have to have a precision of at least 0.1 seconds.

This is similar to the concept of man-hours: a job that takes 60 hours can be completed in only 6 hours if 10 workers are splitting the job. Here we can have 60 seconds of sleep time e.g. in 10 parallel threads, thus requiring only 6 seconds for the whole job to be completed.

Example

The program MyProgram creates 14 threads, each thread sleeps for 5 seconds:

MyProgram[5.016,70.105]

The execution time is greater than 5 seconds, and the total sleep time is greater than 70 seconds because of overhead.

Adám

Posted 2016-06-16T07:27:45.587

Reputation: 37 779

2I've read the question several times and I don't get it. Can you clarify a bit? Why "10 seconds" and a delay of "70 seconds"? How are all those times related? – Luis Mendo – 2016-06-16T07:31:02.050

@LuisMendo The whole program terminates in less than 10 seconds (about 5 in the example), but it had several parallel calls to a delay procedure. Each delay was 5 seconds long. 14 parallel delays of 5 seconds is 70 seconds. – Adám – 2016-06-16T07:33:32.930

@LuisMendo Better now? – Adám – 2016-06-16T07:42:59.747

3How many threads can we assume will be executed in parallel? – miles – 2016-06-16T07:47:08.303

@miles You chose how many you want, but it will have to be at least seven in order to finish on time. Or maybe I'm not understanding your question. – Adám – 2016-06-16T08:30:14.503

3What precision is required for the time in output? – edc65 – 2016-06-16T09:15:08.960

@edc65 Less than a second, so let us say 0.1 s. – Adám – 2016-06-16T09:15:59.537

Are you counting overhead in the "executed sleep time"? Your example seems to indicate so. Meaning, does our code have to explicitly have calculable sleep >60 (e.g., 10 threads at 6 seconds each), or just the actual runtime of the threads must be >60? – AdmBorkBork – 2016-06-16T13:13:43.357

@TimmyD The sleep itself must be ≥ 60. However, the sleep must actually be timed, and then it will be > 60 because of overhead (if nothing else, then in the timing procedure itself). – Adám – 2016-06-16T13:18:44.860

20I wonder if this will cause all the golfing language authors to engage in a mad dash to add multi-threading to their creations... – Adám – 2016-06-16T14:23:08.220

1I believe @miles wanted to know how many threads are the maximum. For threads >= 2/4/8 depending on the processor, the programs will not work. – NoOneIsHere – 2016-06-16T14:31:44.213

3@NoOneIsHere Ah, well, a properly implemented sleep method should not busy a core, so the number of threads may exceed the number of (virtual) processors. – Adám – 2016-06-16T15:08:44.737

This being code golf, do solutions have to be "golfed" (i.e. compressed to within an inch of their lives), or would you welcome an ungolfed solution in Golang (whose gofmt makes this tricky)? – Rob – 2016-06-16T15:09:07.480

@miles If you need real-time computed threads, then you may assume 8 – otherwise this isn't possible, I think. – Adám – 2016-06-16T15:09:21.773

@Rob In some languages the obvious solution is already (close to) the shortest. Besides, one way to view code-golf challenges is finding the shortest solution in EACH language. Otherwise Jelly will win most of the time... So: go ahead. – Adám – 2016-06-16T15:17:20.297

Done, thanks very much @Adám – Rob – 2016-06-16T15:50:50.997

Is the output format strictly [a,b], or can it be any sort of delimited list / array, whatever is convenient for the language? – Digital Trauma – 2016-06-16T15:59:14.790

@Rob to undo gofmt, try http://codebeautify.org/javaviewer

– cat – 2016-06-16T16:43:40.963

Thanks @cat! @DigitalTrauma, yeah, that'd shave off some characters! Perhaps it's not too strict a rule? – Rob – 2016-06-16T16:47:17.497

@DigitalTrauma Adam, in a comment said "Any output format is good"; I wish this were in the question

– cat – 2016-06-16T16:55:03.813

(why) do we need a new [tag:multi-threading] tag? – cat – 2016-06-16T17:54:10.393

1@cat Format phase added. Was there any such tag before? I think it is an interesting subject we hadn't had any challenges about. But I look forward to seeing more. By the way, my tag suggestion was peer reviewed and accepted. – Adám – 2016-06-16T18:12:17.747

I have a solution that works great if threads can burn CPU time instead of sleeping - is that OK, or is it absolutely required to call sleep? – nneonneo – 2016-06-17T08:05:46.937

@nneonneo Feel free to post it, even if it isn't eligible to win. – Adám – 2016-06-17T08:13:53.070

1@Adám it originally was unclear, and I haven't retracted my close vote. But I think is it too broad now. – Rɪᴋᴇʀ – 2016-06-17T13:47:30.660

It's unclear what exactly counts as waiting multiple times. Do I have to fire a thread to not do anything, or is it OK to schedule a task? What if my language doesn't have threads, just an event loop (say, Javascript)? Is it okay then to set up a timer? – John Dvorak – 2016-06-17T17:11:38.067

2@JanDvorak The challenge says "wait" - it's pretty clear from that and the comments that the threads are supposed to sleep (as opposed to busy-waiting). – Mego – 2016-06-17T17:22:48.760

@JanDvorak Feel free to submit such a solution, even though it will not be eligible to win. – Adám – 2016-06-17T19:16:45.087

I'm asking about setting up timers. I wouldn't expect that to be legal, but you have blessed the Javascript javascript nevertheless. – John Dvorak – 2016-06-17T19:17:55.553

1Recommended reading: The Mythical Man-Month. – sergiol – 2017-02-19T00:46:17.233

Answers

16

Dyalog APL, 65 27 23 21 bytes

(⌈/,+/)⎕TSYNC⎕DL&¨9/7

I.e.:

      (⌈/,+/)⎕TSYNC⎕DL&¨9/7
7.022 63.162

Explanation:

  • ⎕DL&¨9/7: spin off 9 threads, each of which waits for 7 seconds. ⎕DL returns the actual amount of time spent waiting, in seconds, which will be the same as its argument give or take a few milliseconds.
  • ⎕TSYNC: wait for all threads to complete, and get the result for each thread.
  • (⌈/,+/): return the longest execution time of one single thread (during the execution of which all other threads finished, so this is the actual runtime), followed by the sum of the execution time of all threads.

Try it online!

marinus

Posted 2016-06-16T07:27:45.587

Reputation: 30 224

This won't work if executed at 23:59:57. However, you're on the right track... While you are already the shortest, can you golf away another 40 bytes? – Adám – 2016-06-16T21:57:39.087

1@Adám: no, but I can golf away 38 bytes. It's quite obvious, I don't know why I didn't think of this the first time around. – marinus – 2016-06-16T22:39:18.927

There you go. Only another 6 bytes until you get a checkmark. The three things you have to do are pretty obvious too, saving 1, 2, and 3 bytes respectively. – Adám – 2016-06-16T22:43:27.953

Very nice, you found number 1 and number 3. Number 2 isn't really golfing, as much as an implementation alternative... – Adám – 2016-06-16T23:23:27.160

Number 2: As you don't need arguments, just make it into a tfn body. – Adám – 2016-06-17T19:25:32.160

@Adám: if you'll accept it like that, sure, though it's not quite a function then but more like a snippet (a tfn would need ∇F\n body\n , and if you'd actually want to return something you'd need to do ∇R←F\n R←body\n ). – marinus – 2016-06-18T21:53:59.270

I often submit programs (I included "program" in the OP) like that. And returning doesn't necessarily mean as a result, (implied) printing is fine. In any case, you certainly do not need dels (), as ⎕FX 'F' 'body' is enough. – Adám – 2016-06-18T22:10:23.930

I spotted a problem. If the last ⎕DL 7 takes slightly longer than the previous ones, then ⌈/ will return its run time, but since the first ⎕DL 7 began before that, the total time is longer. I'm afraid you'll need (⊃,+/-⊃)⎕TSYNC⎕DL&¨8,9/7 or something like that. – Adám – 2016-06-18T22:15:29.040

@Adám: that problem actually doesn't occur, the threads all start within a microsecond of each other, at least this: ⌈/ { (⌈/-⌊/)⎕TSYNC{⎕TS[7]}&¨⍳7 } ¨ ⍳1000 consistently gives me 1 (and sometimes 999 when you time it just right, but that's just at the very end of a second). – marinus – 2016-06-18T22:40:26.273

Ok, you get your checkmark. – Adám – 2016-06-18T22:48:38.930

18

Python 2, 172 bytes

import threading as H,time as T
m=T.time
z=H.Thread
s=m()
r=[]
def f():n=m();T.sleep(9);f.t+=m()-n
f.t=0
exec"r+=[z(None,f)];r[-1].start();"*8
map(z.join,r)
print m()-s,f.t

This requires an OS with time precision greater than 1 second to work properly (in other words, any modern OS). 8 threads are created which sleep for 9 seconds each, resulting in a realtime runtime of ~9 seconds, and a parallel runtime of ~72 seconds.

Though the official documentation says that the Thread constructor should be called with keyword arguments, I throw caution to the wind and use positional arguments anyway. The first argument (group) must be None, and the second argument is the target function.

nneonneo pointed out in the comments that attribute access (e.g. f.t) is shorter than list index access (e.g. t[0]). Unfortunately, in most cases, the few bytes gained from doing this would be lost by needing to create an object that allows user-defined attributes to be created at runtime. Luckily, functions support user-defined attributes at runtime, so I exploit this by saving the total time in the t attribute of f.

Try it online

Thanks to DenkerAffe for -5 bytes with the exec trick.

Thanks to kundor for -7 bytes by pointing out that the thread argument is unnecessary.

Thanks to nneonneo for -7 bytes from miscellaneous improvements.

Mego

Posted 2016-06-16T07:27:45.587

Reputation: 32 998

You can save two bytes by removing the argument to f(), and the last two arguments to Thread (thus removing 7 characters) and using t.append(m()-n) to avoid assigning a local variable t (using 5 more characters than +=.) – Nick Matteo – 2016-06-16T15:50:10.350

And you can save five more by keeping the sum instead of a list of times: initialize t with t=[0], replace the append by t[0]+=m()-n, and replace sum(t) by t[0]. – Nick Matteo – 2016-06-16T15:57:31.647

Thread names can be omitted. – pppery – 2016-06-16T16:13:23.417

@ppperry: not if you need to use the subsequent positional arguments (but as I mentioned in previous comments, you can actually elide those.) – Nick Matteo – 2016-06-16T18:52:58.767

Save three bytes by using import threading as H,time as t; save another two bytes by using z=H.Thread and map(z.join,r); save another two bytes by stashing the total time as an attribute (e.g. T.z+=m()-n) – nneonneo – 2016-06-17T19:34:05.933

12

Bash + GNU utilities, 85

\time -f%e bash -c 'for i in {1..8};{ \time -aoj -f%e sleep 8&};wait'
paste -sd+ j|bc

Forces the use of the time executable instead of the shell builtin by prefixing with a \.

Appends to a file j, which must be empty or non-existent at the start.

Digital Trauma

Posted 2016-06-16T07:27:45.587

Reputation: 64 644

What about a forking script like; if [ $1 -lt 9 ];then { ./a $(( $1 + 1 )) &};sleep 7;fi or somesuch? Would that be against the rules, or something I'm not understanding about the spec? [edit; I missed the requirement for output. Ooh, that makes it interesting!] – Dewi Morgan – 2016-06-17T17:48:20.033

2@DewiMorgan Yes, the output requirement makes it quite a bit harder. What you suggest could be golfed to something like (($1<9))&&$0 $[$1+1]&sleep 7 – Digital Trauma – 2016-06-17T18:01:48.767

9

Go - 189 bytes

Thanks @cat!

package main
import(."fmt";."time");var m,t=60001,make(chan int,m);func main(){s:=Now();for i:=0;i<m;i++{go func(){Sleep(Millisecond);t<-0}()};c:=0;for i:=0;i<m;i++{c++};Print(Since(s),c)}

Outputs (ms): 160.9939ms,60001 (160ms to wait 60.001 seconds)

Rob

Posted 2016-06-16T07:27:45.587

Reputation: 191

1Hello, and welcome to PPCG! This comment, @Rob In some languages the obvious solution is already (close to) the shortest. Besides, one way to view code-golf challenges is finding the shortest solution in EACH language. Otherwise Jelly will win most of the time... So: go ahead., does not mean that you should not try to golf your answer, but that it is OK if it does not win. Can you please add a golfed solution? – NoOneIsHere – 2016-06-16T15:51:20.310

I'm sorry, I just read your edit. For golfed, you could maybe remove newlines and spaces, or change tot to something like q. – NoOneIsHere – 2016-06-16T15:52:54.223

@NoOneIsHere, thanks for that, I'd overlooked that variable completely! Also banged together m and t. – Rob – 2016-06-16T15:59:56.963

1http://codebeautify.org/javaviewer -- click minify – cat – 2016-06-16T16:44:31.780

Try removing whitespace and newlines like other solutions, too. – cat – 2016-06-16T16:46:16.620

Go can probably multithread on a zero-core machine :D – cat – 2016-06-16T16:48:01.033

Haha, it is an especially good scheduler... ^_^ – Rob – 2016-06-16T16:49:36.860

199 bytes (should compile, it's been a while since I've used golang) – cat – 2016-06-16T16:59:19.110

Noice! Submit your answer! You could also remove the format args and use the variadic print thinking about it... – Rob – 2016-06-16T17:06:29.597

package main import(."fmt";."time");var m,t=60001,make(chan int,m);func main(){s:=Now();for i:=0;i<m;i++{go func(){Sleep(Millisecond);t<-0}()};c:=0;for i:=0;i<m;i++{c++};Print(Since(s),c)} – Rob – 2016-06-16T17:09:28.617

First, you can use newlines instead of semicolons for readability. Second, you can save 9 bytes by reusing the var statement to declare i and s, eliminating c, and removing the i initializations from the loops. Third. this program isn't strictly correct, because the main goroutine doesn't wait for the sleepers. Theoretically, the scheduler could execute only the main goroutine, incrementing c 60001 times, printing it, then exiting without ever sleeping in the spawned goroutines. So c++ needs to be replaced with <-t. This program is 9 bytes shorter: https://pastebin.com/Z0Xu2Dzq

– Purple P – 2019-08-11T16:15:54.487

8

Bash 196 117 114 93 bytes

Updated to support better time precision by integrating suggestions from @manatwork and @Digital Trauma as well as a few other space optimizations:

d()(date +$1%s.%N;)
b=`d`
for i in {1..8};{ (d -;sleep 8;d +)>>j&}
wait
bc<<<`d`-$b
bc<<<`<j`

Note that this assumes the j file is absent at the beginning.

Julie Pelletier

Posted 2016-06-16T07:27:45.587

Reputation: 719

2function ss(), b=\date +%s`` → b=$SECONDS, expr $t + $i$[t+i], \cat j`` → $(<j) and generally see Tips for golfing in Bash about how to reduce it to this: http://pastebin.com/DDqUaDug – manatwork – 2016-06-16T09:22:18.527

To reduce it more, better write directly a formula to the file j. I mean instead of 5↵5↵5↵… write +5+5+5… – then load it all directly into arithmetic evaluation and spare the second loop: http://pastebin.com/LB0BjDMZ

– manatwork – 2016-06-16T09:26:05.120

As minimum precision was specified later, forget the b=\date +%s`` → b=$SECONDS suggestion. – manatwork – 2016-06-16T09:36:25.437

@manatwork Yeah, sorry about that. – Adám – 2016-06-16T09:48:45.720

1

As bash does only integer arithmetic, the entire solution needs to be rewritten to use an external tool for calculation. Typically bc: http://pastebin.com/eYFEVUuz

– manatwork – 2016-06-16T09:52:25.473

Me stupid. Why I used an explicit printf in the earlier suggested code…? http://pastebin.com/BihmfSRb

– manatwork – 2016-06-16T10:04:37.657

@manatwork I suggest leaving this solution, but with a note that it is int-only and that the rules changed. – Adám – 2016-06-16T10:23:08.310

@manatwork: thanks for the suggestions. – Julie Pelletier – 2016-06-16T15:05:47.413

Here's my attempt using the /usr/bin/time binary - down to 85 bytes: \time -f%e bash -c 'for i in {1..8};{ \time -aoj -f%e sleep 8&};wait';paste -sd+ j|bc. Waits for 8x8sec instead of 13x5sec. Output is newline-separated - not sure if thats OK or not - see comment to OP

– Digital Trauma – 2016-06-16T16:25:05.927

"Any output format is good"

– Digital Trauma – 2016-06-16T16:33:31.467

@DigitalTrauma: I like your solution but it uses an entirely different approach which would justify a separate answer. I had thought of using time but didn't realize I could force the external binary with \\. – Julie Pelletier – 2016-06-16T16:47:41.130

1

@JuliePelletier Ok, I'll post it as my own answer. Still, I think you can still apply some of the golfing techniques to your answer without significantly changing the approach: http://pastebin.com/ssYzVs1n (93 bytes)

– Digital Trauma – 2016-06-16T17:19:24.180

BTW, the +/- thing in the date format string is really clever :) – Digital Trauma – 2016-06-16T18:31:21.407

8

JavaScript (ES6), 148 bytes

with(performance)Promise.all([...Array(9)].map(_=>new Promise(r=>setTimeout(_=>r(t+=now()),7e3,t-=now())),t=0,n=now())).then(_=>alert([now()-n,t]));

Promises to wait 9 times for 7 seconds for a total of 63 seconds (actually 63.43 when I try), but only actually takes 7.05 seconds of real time when I try.

Neil

Posted 2016-06-16T07:27:45.587

Reputation: 95 035

8

C, 127 bytes (spins CPU)

This solution spins the CPU instead of sleeping, and counts time using the times POSIX function (which measures CPU time consumed by the parent process and in all waited-for children).

It forks off 7 processes which spin for 9 seconds apiece, and prints out the final times in C clocks (on most systems, 100 clock ticks = 1 second).

t;v[4];main(){fork(fork(fork(t=time(0))));while(time(0)<=t+9);wait(0);wait(0);wait(0)>0&&(times(v),printf("%d,%d",v[0],v[2]));}

Sample output:

906,6347

meaning 9.06 seconds real time and 63.47 seconds total CPU time.

For best results, compile with -std=c90 -m32 (force 32-bit code on a 64-bit machine).

nneonneo

Posted 2016-06-16T07:27:45.587

Reputation: 11 445

6

Scratch - 164 bytes (16 blocks)

when gf clicked
set[t v]to[
repeat(9
  create clone of[s v
end
wait until<(t)>[60
say(join(join(t)[ ])(timer
when I start as a clone
wait(8)secs
change[t v]by(timer

Visual script

See it in action here.

Uses a variable called 't' and a sprite called 's'. The sprite creates clones of itself, each of which waits 8 seconds, and increments a variable clocking the entire wait time. At the end it says the total execution time and the total wait time (for example, 65.488 8.302).

Scimonster

Posted 2016-06-16T07:27:45.587

Reputation: 2 905

5

PowerShell v4, 144 bytes

$d=date;gjb|rjb
1..20|%{sajb{$x=date;sleep 3;((date)-$x).Ticks/1e7}>$null}
while(gjb -s "Running"){}(gjb|rcjb)-join'+'|iex
((date)-$d).Ticks/1e7

Sets $d equal to Get-Date, and clears out any existing job histories with Get-Job | Remove-Job. We then loop 1..20|%{...} and each iteration execute Start-Job passing it the script block {$x=date;sleep 3;((date)-$x).ticks/1e7} for the job (meaning each job will execute that script block). We pipe that output to >$null in order to suppress the feedback (i.e., job name, status, etc.) that gets returned.

The script block sets $x to Get-Date, then Start-Sleep for 3 seconds, then takes a new Get-Date reading, subtracts $x, gets the .Ticks, and divides by 1e7 to get the seconds (with precision).

Back in the main thread, so long as any job is still -Status "Running", we spin inside an empty while loop. Once that's done, we Get-Job to pull up objects for all the existing jobs, pipe those to Receive-Job which will pull up the equivalent of STDOUT (i.e., what they output), -join the results together with +, and pipe it to iex (Invoke-Expression and similar to eval). This will output the resultant sleep time plus overhead.

The final line is similar, in that it gets a new date, subtracts the original date stamp $d, gets the .Ticks, and divides by 1e7 to output the total execution time.


NB

OK, so this is a little bendy of the rules. Apparently on first execution, PowerShell needs to load a bunch of .NET assemblies from disk for the various thread operations as they're not loaded with the default shell profile. Subsequent executions, because the assemblies are already in memory, work fine. If you leave the shell window idle long enough, you'll get PowerShell's built-in garbage collection to come along and unload all those assemblies, causing the next execution to take a long time as it re-loads them. I'm not sure of a way around this.

You can see this in the execution times in the below runs. I started a fresh shell, navigated to my golfing directory, and executed the script. The first run was horrendous, but the second (executed immediately) worked fine. I then left the shell idle for a few minutes to let garbage collection come by, and then that run is again lengthy, but subsequent runs again work fine.

Example runs

Windows PowerShell
Copyright (C) 2014 Microsoft Corporation. All rights reserved.

PS H:\> c:

PS C:\> cd C:\Tools\Scripts\golfing

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
63.232359
67.8403415

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
61.0809705
8.8991164

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
62.5791712
67.3228933

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
61.1303589
8.5939405

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
61.3210352
8.6386886

PS C:\Tools\Scripts\golfing>

AdmBorkBork

Posted 2016-06-16T07:27:45.587

Reputation: 41 581

1I'll say that's fine. :-) – Adám – 2016-06-16T15:14:08.157

5

Javascript (ES6), 212 203 145 bytes

This code creates 10 images with a time interval of exactly 6 seconds each, upon loading.

The execution time goes a tiny bit above it (due to overhead).

This code overwrites everything in the document!

P=performance,M=P.now(T=Y=0),document.body.innerHTML='<img src=# onerror=setTimeout(`T+=P.now()-M,--i||alert([P.now()-M,T])`,6e3) >'.repeat(i=10)

This assumes that you use a single-byte encoding for the backticks, which is required for the Javascript engine to do not trip.


Alternativelly, if you don't want to spend 6 seconds waiting, here's a 1-byte-longer solution that finishes in less than a second:

P=performance,M=P.now(T=Y=0),document.body.innerHTML='<img src=# onerror=setTimeout(`T+=P.now()-M,--i||alert([P.now()-M,T])`,600) >'.repeat(i=100)

The difference is that this code waits 600ms across 100 images. This will give a massive ammount of overhead.


Old version (203 bytes):

This code creates 10 iframes with a time interval of exactly 6 seconds each, instead of creating 10 images.

for(P=performance,M=P.now(T=Y=i=0),D=document,X=_=>{T+=_,--i||alert([P.now()-M,T])};i<10;i++)I=D.createElement`iframe`,I.src='javascript:setTimeout(_=>top.X(performance.now()),6e3)',D.body.appendChild(I)


Original version (212 bytes):

P=performance,M=P.now(T=Y=0),D=document,X=_=>{T+=_,Y++>8&&alert([P.now()-M,T])},[...''+1e9].map(_=>{I=D.createElement`iframe`,I.src='javascript:setTimeout(_=>top.X(performance.now()),6e3)',D.body.appendChild(I)})

Ismael Miguel

Posted 2016-06-16T07:27:45.587

Reputation: 6 797

2+1 Very nice and different approach. What would happen in a single-threaded browser? – Adám – 2016-06-16T18:15:37.503

2@Adám No change in behaviour. There would still be a delay of around 6 seconds. Firefox (a single-threaded browser) sometimes will output funny stuff like an execution time of 59999.<something>. – Ismael Miguel – 2016-06-16T18:17:23.377

4

Ruby, 92

n=->{Time.now}
t=n[]
a=0
(0..9).map{Thread.new{b=n[];sleep 6;a+=n[]-b}}.map &:join
p n[]-t,a

histocrat

Posted 2016-06-16T07:27:45.587

Reputation: 20 600

4

Javascript (ES6), 108 92 bytes

I'm making a new answer since this uses a slightly different aproach.

It generates a massive amount of setTimeouts, which are almost all executed with 4ms between them.

Each interval is of 610 milliseconds, over a total of 99 intervals.

M=(N=Date.now)(T=Y=0),eval('setTimeout("T+=N()-M,--i||alert([N()-M,T])",610);'.repeat(i=99))

It usually runs within 610ms, for a total execution time of around 60.5 seconds.

This was tested on Google Chrome version 51.0.2704.84 m, on windows 8.1 x64.


Old version (108 bytes):

P=performance,M=P.now(T=Y=0),eval('setTimeout("T+=P.now()-M,--i||alert([P.now()-M,T])",610);'.repeat(i=99))

Ismael Miguel

Posted 2016-06-16T07:27:45.587

Reputation: 6 797

4

Clojure, 135 120 111 109 bytes

(let[t #(System/nanoTime)s(t)f #(-(t)%)][(apply +(pmap #(let[s(t)](Thread/sleep 7e3)%(f s))(range 9)))(f s)])

Formatted version with named variables:

(let [time #(System/currentTimeMillis)
      start (time)
      fmt #(- (time) %)]
  [(apply +
           (pmap #(let [thread-start (time)]
                   (Thread/sleep 7e3)
                   %
                   (fmt thread-start)) (range 9)))
   (fmt start)])

output (in nanoseconds):

[62999772966 7001137032]

Changed format. Thanks Adám, I might have missed that format specification in the question when I read it.

Changed to nanoTime for golfing abilities.

Thanks cliffroot, I totally forgot about scientific notation and can't believe I didn't see apply. I think I used that in something I was golfing yesterday but never posted. You saved me 2 bytes.

Chris F

Posted 2016-06-16T07:27:45.587

Reputation: 81

Welcome to PPCG! Nice first post! You might be able to ask the OP about the output format. – Rɪᴋᴇʀ – 2016-06-17T20:04:55.930

No need to reverse. OP: by any means and in any format. – Adám – 2016-06-19T18:36:25.607

seems like you can use 7e3 instead of 7000 and use apply instead of reduce – cliffroot – 2016-07-08T14:39:48.743

3

Rust, 257, 247 bytes

I use the same times as Mego's Python answer.

Really the only slightly clever bit is using i-i to get a Duration of 0 seconds.

fn main(){let n=std::time::Instant::now;let i=n();let h:Vec<_>=(0..8).map(|_|std::thread::spawn(move||{let i=n();std::thread::sleep_ms(9000);i.elapsed()})).collect();let mut t=i-i;for x in h{t+=x.join().unwrap();}print!("{:?}{:?}",t,i.elapsed());}

Prints:

Duration { secs: 71, nanos: 995877193 }Duration { secs: 9, nanos: 774491 }

Ungolfed:

fn main(){
    let n = std::time::Instant::now;
    let i = n();
    let h :Vec<_> =
        (0..8).map(|_|
            std::thread::spawn(
                move||{
                    let i = n();
                    std::thread::sleep_ms(9000);
                    i.elapsed()
                }
            )
        ).collect();
    let mut t=i-i;
    for x in h{
        t+=x.join().unwrap();
    }
    print!("{:?}{:?}",t,i.elapsed());
}

Edit: good old for loop is a bit shorter

raggy

Posted 2016-06-16T07:27:45.587

Reputation: 491

3

JavaScript (ES6, using WebWorkers), 233 215 bytes

c=s=0;d=new Date();for(i=14;i-->0;)(new Worker(URL.createObjectURL(new Blob(['a=new Date();setTimeout(()=>postMessage(new Date()-a),5e3)'])))).onmessage=m=>{s+=m.data;if(++c>13)console.log((new Date()-d)/1e3,s/1e3)}

UPD: replaced the way a worker is executed from a string with a more compact and cross-browser one, in the aspect of cross-origin policies. Won't work in Safari, if it still have webkitURL object instead of URL, and in IE.

bodqhrohro

Posted 2016-06-16T07:27:45.587

Reputation: 583

1I'm getting an error when I run this: { "message": "Uncaught SecurityError: Failed to construct 'Worker': Script at 'data:application/javascript,a%3Dnew%20Date()%3BsetTimeout(()%3D%3EpostMessage(new%20Date()-a)%2C5e3)' cannot be accessed from origin 'null'.", "filename": "http://stacksnippets.net/js", "lineno": 13, "colno": 45 } – James – 2016-06-16T20:42:38.857

3

Python 2, 130 bytes

import thread as H,time as T
m=T.clock;T.z=m()
def f(k):T.sleep(k);T.z+=m()
exec"H.start_new_thread(f,(7,));"*9
f(8);print m(),T.z

This is a derivation of Mego's answer, but it's sufficiently different that I thought it should be a separate answer. It is tested to work on Windows.

Basically, it forks off 9 threads, which sleep for 7 seconds while the parent sleeps for 8. Then it prints out the times. Sample output:

8.00059192923 71.0259046024

On Windows, time.clock measures wall time since the first call.

nneonneo

Posted 2016-06-16T07:27:45.587

Reputation: 11 445

It's important to note that this only works on Windows - time.clock() behaves differently between Windows and UNIX/Linux platforms.

– Mego – 2016-06-17T23:48:15.810

3

Perl 6, 72 71 bytes

There might be a shorter way to do this

say sum await map {start {sleep 7;now -ENTER now}},^9;say now -INIT now

this outputs

63.00660729694
7.0064013

Hotkeys

Posted 2016-06-16T07:27:45.587

Reputation: 1 015

2

Java, 358 343 337 316 313 bytes

import static java.lang.System.*;class t extends Thread{public void run(){long s=nanoTime();try{sleep(999);}catch(Exception e){}t+=nanoTime()-s;}static long t,i,x;public static void main(String[]a)throws Exception{x=nanoTime();for(;++i<99;)new t().start();sleep(9000);out.println((nanoTime()-x)/1e9+" "+t/1e9);}}

and ungolfed

import static java.lang.System.*;

class t extends Thread {
    public void run() {
        long s = nanoTime();
        try {
            sleep(999);
        } catch (Exception e) {
        }
        t += nanoTime() - s;
    }

    static long t,i,x;

    public static void main(String[] a) throws Exception {
        x = nanoTime();
        for (; ++i < 99;)
            new t().start();
        sleep(9000);
        out.println((nanoTime() - x) / 1e9 + " " + t / 1e9);
    }
}

please don't try it at home, as this solution is not thread safe.

Edit:

I took @A Boschman's and @Adám's suggestions, and now my program require less than 10 seconds to run, and it's shorter by 15 bytes.

user902383

Posted 2016-06-16T07:27:45.587

Reputation: 1 360

2You're inside a child of the Thread class, can't you omit the Thread. at the static sleep() method calls? Also, won't this program terminate in slightly over 10 seconds, disqualifying it? – Reinstate Monica – 2016-06-16T12:58:35.650

@ABoschman thanks for suggestion, and its fixed by now, it doesn't run more than 10 sec anymore – user902383 – 2016-06-16T13:46:33.577

@user902383 If I recall correctly, you can omit the public keyword as it is implicit. Also, int may not be required when defining a function (try it, and tell me if that works) – Katenkyo – 2016-06-16T13:47:53.160

1

Also, don't forget we have a great userbase of tips for golfing in java :)

– Katenkyo – 2016-06-16T13:48:45.260

@Katenkyo public isn't implicit but you're correct that it's not required. If you omit it your class will be package private. – Poke – 2016-06-16T13:56:22.147

1This seems susceptible to read-modify-write race conditions. You don't have any sort of locking or anything around your static long t. I only mention this because the spec says "Both time values have to have a precision of at least 0.1 second." – Poke – 2016-06-16T13:59:36.153

1You can remove the long before the s and add ,s to the static long t,i,s; to save a few bytes. – Kevin Cruijssen – 2016-06-17T07:36:34.873

2

Mathematica, 109 bytes

a=AbsoluteTiming;LaunchKernels@7;Plus@@@a@ParallelTable[#&@@a@Pause@9,{7},Method->"EvaluationsPerKernel"->1]&

Anonymous function. Requires a license with 7+ sub-kernels to run. Takes 9 seconds realtime and 63 seconds kernel-time, not accounting for overhead. Make sure to only run the preceding statements once (so it doesn't try to re-launch kernels). Testing:

In[1]:= a=AbsoluteTiming;LaunchKernels@7;func=Plus@@@a@ParallelTable[#&@@a@Pause
@9,{7},Method->"EvaluationsPerKernel"->1]&;

In[2]:= func[]

Out[2]= {9.01498, 63.0068}

In[3]:= func[]

Out[3]= {9.01167, 63.0047}

In[4]:= func[]

Out[4]= {9.00587, 63.0051}

LegionMammal978

Posted 2016-06-16T07:27:45.587

Reputation: 15 731

2Leave it to Wolfram to put license restrictions on forking a child process. – Mario Carneiro – 2016-06-17T04:59:33.447

2

C (with pthreads), 339 336 335 bytes

#include<stdio.h>
#include<sys/time.h>
#include<pthread.h>
#define d double
d s=0;int i;pthread_t p[14];d t(){struct timeval a;gettimeofday(&a,NULL);return a.tv_sec+a.tv_usec/1e6;}
h(){d b=t();sleep(5);s+=t()-b;}
main(){d g=t();for(i=14;i-->0;)pthread_create(&p[i],0,&h,0);for(i=14;i-->0;)pthread_join(p[i],0);printf("%f %f",t()-g,s);}

bodqhrohro

Posted 2016-06-16T07:27:45.587

Reputation: 583

2

Javascript (ES6), 105 bytes

((t,c,d)=>{i=t();while(c--)setTimeout((c,s)=>{d+=t()-s;if(!c)alert([t()-i,d])},8e3,c,t())})(Date.now,8,0)

Updated version: 106 bytes Borrowed from @Ismael Miguel as he had the great idea to lower sleep time and raise intervals.

((t,c,d)=>{i=t();while(c--)setTimeout((c,s)=>{d+=t()-s;if(!c)alert([t()-i,d])},610,c,t())})(Date.now,99,0)

Javascript Ungolfed, 167 bytes

(function(t, c, d){
 i = t();
 while(c--){
  setTimeout(function(c, s){
   d += t() - s;
   if (!c) alert([t() - i, d])
  }, 8e3, c, t())
 }
})(Date.now, 8, 0)

Andrew

Posted 2016-06-16T07:27:45.587

Reputation: 121

2Instead of d+=t()-s;if(!c)alert([t()-i,d]), you can write d+=t()-s;c||alert([t()-i,d]), which will save a few bytes. Also, if you remove the function and rewrite it all, you can compete with my 92-byte long solution: for(c=8,i=(t=Date.now)(d=0);c--;)setTimeout((c,s)=>{d+=t()-s;c||alert([t()-i,d])},8e3,c,t()). And yes, this one is also 92 bytes long. – Ismael Miguel – 2016-06-17T13:01:22.983

2

C90 (OpenMP), 131 Bytes (+ 17 for env variable) = 148 Bytes

#include <omp.h>
#define o omp_get_wtime()
n[4];main(t){t=o;
#pragma omp parallel
while(o-9<t);times(n);printf("%d,%f",n[0],o-t);}

Example Output:

7091,9.000014

Notes:

7091 is in cycles (100/sec), so the program ran for 70 seconds

Could be much shorter if I figured a way to get a timer to work other than omp_get_wtime() because then I could remove the include statement aswell.

Run with OMP_NUM_THREADS=9

dj0wns

Posted 2016-06-16T07:27:45.587

Reputation: 328

You can set up the env var, but you would have to count the bytes to do so, except if the setting you choose is a common default. – Adám – 2016-06-19T18:51:15.377

@Adám Thanks, that's what I thought, it saves 6 or 7 bytes – dj0wns – 2016-06-20T17:25:37.953

2

Python 2, 132 bytes

Uses a process pool to spawn 9 processes and let each one sleep for 7 seconds.

import time as t,multiprocessing as m
def f(x):d=s();t.sleep(x);return s()-d
s=t.time
a=s()
print sum(m.Pool(9).map(f,[7]*9)),s()-a

Prints total accumulated sleeptime first, then the actual runtime:

$ python test.py
63.0631158352 7.04391384125

moooeeeep

Posted 2016-06-16T07:27:45.587

Reputation: 171

2

Perl, 101 bytes

use Time::HiRes<time sleep>;pipe*1=\time,0;
print time-$1,eval<1>if open-print{fork&fork&fork}-sleep 9

Forks 7 child processes, each of which wait 9 seconds.

Sample Output:

perl wait-one-minute.pl
9.00925707817078-63.001741

primo

Posted 2016-06-16T07:27:45.587

Reputation: 30 891

2

Common Lisp (SBCL) 166 bytes:

(do((m #1=(get-internal-real-time))(o(list 0)))((>(car o)60000)`(,(car o),(- #1#m)))(sb-thread:make-thread(lambda(&aux(s #1#))(sleep 1)(atomic-incf(car o)(- #1#s)))))

This just spawns threads that sleep and then atomically increment the time took, with an outer-loop that spins waiting for the total time to be more than 60000 ticks (i.e. 60s on sbcl). The counter is stored in a list due to limitations to the types of places atomic-incf can modify. This may run out of space before terminating on faster machines.

Ungolfed:

(do ((outer-start (get-internal-real-time))
       (total-inner (list 0)))
      ((> (car total-inner) 60000)
       `(,(car total-inner)
      ,(- (get-internal-real-time) outer-start)))
    (sb-thread:make-thread
     (lambda (&aux(start (get-internal-real-time)))
       (sleep 1)
       (atomic-incf (car total-inner) (- (get-internal-real-time) start)))))

Jason

Posted 2016-06-16T07:27:45.587

Reputation: 201

1

c++, 332 358 357 bytes

Thanks Adám!

#include <iostream>
#include <chrono>
#include <thread>
#define n(x)auto x=chrono::steady_clock::now();
using namespace std;double t=0;void f(){n(s)this_thread::sleep_for(chrono::seconds(9));n(e)t+=(e-s).count()/1e9;}int main(){int i;n(s)thread*a[7];for(i=0;i<7;i++)a[i]=new thread(f);for(i=0;i<7;i++)a[i]->join();n(e)cout<<t<<","<<(e-s).count()/1e9<<"\n";}

Try it online

Johan du Toit

Posted 2016-06-16T07:27:45.587

Reputation: 1 524

1

Ruby (with parallel gem), 123 116 bytes

require'parallel'
n=->{Time.now}
t=n[]
q=0
Parallel.each(1..10,:in_threads=>10){z=n[];sleep 6;q+=n[]-z}
puts n[]-t,q

Edit: Added the "Time.now" reference from the Ruby answer by histocrat.

Gosha U.

Posted 2016-06-16T07:27:45.587

Reputation: 129

1

Groovy, 158 143 characters

d={new Date().getTime()}
s=d(j=0)
8.times{Thread.start{b=d(m=1000)
sleep 8*m
synchronized(j){j+=d()-b}}}addShutdownHook{print([(d()-s)/m,j/m])}

Sample run:

bash-4.3$ groovy wait1minute.groovy
[8.031, 64.055]

manatwork

Posted 2016-06-16T07:27:45.587

Reputation: 17 865

1

Haskell, 278 271 262 246 bytes

import Control.Concurrent.Chan
import Data.Time
import GHC.Conc
t=getCurrentTime
b!a=b=<<flip diffUTCTime<$>t<*>(a>>t)
w=threadDelay$5^10
0#_=t
i#a=a>>(i-1)#a
main=print!do r<-newChan;9#(forkIO$writeChan r!w);getChanContents r>>=print.sum.take 9

! measures the time taken by action a (second argument) and applies b (first argument) to the result.

w is the sleep function.

main is measured itself, and result printed (print!...).

# is replicateM, repeating the given action N times (and returning t because golfing).

Inside the measured part, 9 threads (replicate 9 $ forkIO ...) sleep for 5^10 milliseconds (9.765625 seconds) and post the result (writeChan) to a pipe created by the main thread (newChan), which sums the 9 results up and prints the total (getChanContents >>= print . sum . take 9).

Output:

87.938546708s
9.772032144s

Koterpillar

Posted 2016-06-16T07:27:45.587

Reputation: 111

1@Adám 6^9 > 10^7 (10 seconds). – Koterpillar – 2016-06-17T23:10:38.060

1

Elixir, 168 bytes

import Task;import Enum;IO.puts elem(:timer.tc(fn->IO.puts(map(map(1..16,fn _->async(fn->:timer.tc(fn->:timer.sleep(4000)end)end)end),&(elem(await(&1),0)))|>sum)end),0)

Sample run:

$ elixir thing.exs
64012846
4007547

The output is the total time waited followed by the time the program has run for, in microseconds.

The program spawns 14 Tasks, and awaits each of them by mapping over them, and then finds the sum of their elapsed time. It uses Erlang's timer for measuring time.

Candy Gumdrop

Posted 2016-06-16T07:27:45.587

Reputation: 396

Welcome to the community!! – Erik the Outgolfer – 2016-06-17T15:26:40.173

1

C#, 131 bytes

The following start 9 threads that each wait 6667 milliseconds.
The program run in 6.73 secondes and has the following output : 00:00:06.7116711|604140408
Where "604140408" is the number of tick.
There are 10 000ticks is a millisecond.
So this give ~60.414 seconds. Total execution time and wait time don't have the same output format for golfing reason.

using t=DateTime;var s=t.Now;Task.WhenAll(new t[9].Select(y=>Task.Delay(6667))).Wait();Debug.Write(t.Now-s+"|"+(t.Now-s).Ticks*9);

Here is a fiddle that exceed the limit of execution of time of fiddle. Lower "6667" so that it fix fiddle's criteria if you want to run it.

AXMIM

Posted 2016-06-16T07:27:45.587

Reputation: 209

I don't know C#, but it looks like you do not measure the elapsed sleep time, rather you use a hard-coded value. – Adám – 2016-06-17T16:50:45.603

@Adám, yes indeed I don't measure it because I might not understand something. If I tell all threads to wait for a total time of 60003 milli, what is the point of adding extra execution lines to count the time elapsed since I already know the time? If I add time checking, it's going to take longer only because of the execution time of extra line of code. Beside I wouldn't know how to accurately dissociate wait time from execution time. eg: execution time is 6722 milli and threads waits for 6667 each. So there is a 55milli left for code execution . [See next comment] – AXMIM – 2016-06-17T17:25:57.940

@Adám There may be a small amount of overhead waiting in these 55milli, but I don't understand what you really want about it. The only thing that I could easily calculate is the time it's took to launch all nice thread because first started thread will wait a little longer then the last one. But we are talking about few milliseconds here. So I didn't bother to do it, because yet again I thing I'm missing what you want exactly. I apologize for not getting it, but may be you can shed some light on what is confusing me? – AXMIM – 2016-06-17T17:31:18.403

1The point of this challenge is to start sleeping threads and keep track of their running time. One simple way to do this is take the time before launching the threads, and subtract that from the time when the last thread terminates. – Adám – 2016-06-17T19:20:10.637

I updated the answer to take the existing time differences between before launching threads and last thread terminates multiplied for the number of thread. – AXMIM – 2016-06-20T20:03:15.930

Great. Nice job. – Adám – 2016-06-20T21:22:04.380

1

Matlab, 75 bytes

tic;parpool(9);b=1:9;parfor q=b
a=tic;pause(7);b(q)=toc(a);end
[sum(b);toc]

Quick explanation: parfor creates a parallel for-loop, distributed across the pool of workers. tic and toc measure time elapsed (and are in my opinion one of the best named functions in MATLAB). The last line (an array with the total time slept and the real time elapsed) is outputted since it's not terminated with a semicolon.

Note however that this creates a whopping 9 full-fledged MATLAB processes. Chances are then that this particular program this will not finish within the allotted 10 seconds on your machine. However, I think with a MATLAB installation that has no toolboxes except for the Parallel Computing toolbox installed - installed on a high-end system with SSD - may just be able to finish within 10 seconds. If required, you can tweak the parameters to have less processes sleeping more.

Sanchises

Posted 2016-06-16T07:27:45.587

Reputation: 8 530

The error about b is likely just because you had something in your workspace already. I have no issues on 2015b using parfor q=b – Suever – 2016-06-21T20:01:05.537

@Suever Oh hey, I had a script named b.m in my MATLAB folder. – Sanchises – 2016-06-22T06:23:42.180

1

Common Lisp (Lispworks), 457 bytes

(defun f(n)(labels((h(n b v)(mp:process-run-function nil nil #'(lambda(b v)(progn(let((s(get-internal-real-time)))(sleep 5)(setf(svref v n)(-(get-internal-real-time)s)))(mp:barrier-wait b :pass-through t)))b v)))(let((s(get-internal-real-time))(e 0)(q 0)(v(make-sequence 'vector n :initial-element 0))(b(mp:make-barrier(1+ n))))(dotimes(i n)(h i b v))(mp:barrier-wait b)(setf e(-(get-internal-real-time)s))(dotimes(p n)(setf q(+ q(svref v p))))(list e q))))

ungolfed:

    (defun f (n-thread)
      (labels ((my-process (process-name n barrier vec)
                 (mp:process-run-function
                  process-name
                  nil
                  #'(lambda (barrier vec)
                      (progn
                        (let ((start-time (get-internal-real-time)))
                          (sleep 5)
                          (setf (svref vec n)
                                (- (get-internal-real-time) start-time)))
                        (mp:barrier-wait barrier :pass-through t)))
                  barrier
                  vec)))

        (let ((total-start-time (get-internal-real-time))
              (total-time 0)
              (sum-per-process-time 0)
              (vector (make-sequence 'vector n-thread :initial-element 0))
              (barrier (mp:make-barrier (1+ n-thread))))
          (dotimes (i n-thread)
            (my-process
             (concatenate 'string "process-" (write-to-string i))
             i
             barrier
             vector))
          (mp:barrier-wait barrier)
          (setf total-time (- (get-internal-real-time) total-start-time))
          (dotimes (p n-thread)
            (setf sum-per-process-time
                  (+ sum-per-process-time (svref vector p))))
          (list total-time sum-per-process-time))))

Usage:

CL-USER 1 > (f 14)
(5028 70280)

sadfaf

Posted 2016-06-16T07:27:45.587

Reputation: 101

0

R + Snowfall, 67 UTF-8 bytes

library(snowfall)
sfInit(T,8)
sfSapply(1:8,function(j)Sys.sleep(8))

JDL

Posted 2016-06-16T07:27:45.587

Reputation: 1 135

Hello, and welcome to PPCG! This is [tag:code-golf] so you must include your byte count. If you accept my edit, you don't have to worry about it. – NoOneIsHere – 2016-06-17T16:15:22.957

You also need to include in your header Snowfall. – NoOneIsHere – 2016-06-17T16:26:09.170

How does the output look? – Adám – 2016-06-17T16:51:20.807

What is a "UTF-8 byte"? – Adám – 2016-06-17T19:21:07.390

@Adám There is no such thing. But the byte count is correct (For all usual western encodings, such as ASCII, UTF-8 or CP1252) – AlexR – 2016-06-18T12:46:22.373

@AlexR Good thing I don't use score collecting scripts, as this would probably evaluate to 8. – Adám – 2016-06-19T18:29:55.183

2@Adám: The byte counting userscript I use says "Winner: JDL's answer at -8 bytes". – NoOneIsHere – 2016-07-02T14:52:05.847