81
\$\begingroup\$

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.

\$\endgroup\$
30
  • 2
    \$\begingroup\$ I'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? \$\endgroup\$
    – Luis Mendo
    Commented Jun 16, 2016 at 7:31
  • 3
    \$\begingroup\$ How many threads can we assume will be executed in parallel? \$\endgroup\$
    – miles
    Commented Jun 16, 2016 at 7:47
  • 3
    \$\begingroup\$ What precision is required for the time in output? \$\endgroup\$
    – edc65
    Commented Jun 16, 2016 at 9:15
  • 25
    \$\begingroup\$ I wonder if this will cause all the golfing language authors to engage in a mad dash to add multi-threading to their creations... \$\endgroup\$
    – Adám
    Commented Jun 16, 2016 at 14:23
  • 4
    \$\begingroup\$ @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. \$\endgroup\$
    – Adám
    Commented Jun 16, 2016 at 15:08

40 Answers 40

1
2
1
\$\begingroup\$

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]
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to the community!! \$\endgroup\$ Commented Jun 17, 2016 at 15:26
1
\$\begingroup\$

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
\$\endgroup\$
1
  • 1
    \$\begingroup\$ @Adám 6^9 > 10^7 (10 seconds). \$\endgroup\$ Commented Jun 17, 2016 at 23:10
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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)
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
6
  • \$\begingroup\$ I don't know C#, but it looks like you do not measure the elapsed sleep time, rather you use a hard-coded value. \$\endgroup\$
    – Adám
    Commented Jun 17, 2016 at 16:50
  • \$\begingroup\$ @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] \$\endgroup\$
    – AXMIM
    Commented Jun 17, 2016 at 17:25
  • \$\begingroup\$ @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? \$\endgroup\$
    – AXMIM
    Commented Jun 17, 2016 at 17:31
  • 1
    \$\begingroup\$ The 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. \$\endgroup\$
    – Adám
    Commented Jun 17, 2016 at 19:20
  • \$\begingroup\$ I updated the answer to take the existing time differences between before launching threads and last thread terminates multiplied for the number of thread. \$\endgroup\$
    – AXMIM
    Commented Jun 20, 2016 at 20:03
1
\$\begingroup\$

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

\$\endgroup\$
1
1
\$\begingroup\$

Julia -p 9, 48 bytes

@time show(sum(pmap(_->@elapsed(sleep(7)),1:9)))

Try it online!

  • the -p 9 option launches julia with 9 workers and with the Distributed standard library
  • pmap distributes the tasks over the available workers
  • @elapsed returns the time taken so that they can be sumed
  • @time prints the total time taken
\$\endgroup\$
1
\$\begingroup\$

Javascript, 81 bytes

for(M=(N=Date.now)(T=Y=i=0);i<350;)setTimeout("T+=k=N()-M,--i||alert([k,T])",++i)

From Ismael Miguel's

\$\endgroup\$
0
\$\begingroup\$

R + Snowfall, 67 UTF-8 bytes

library(snowfall)
sfInit(T,8)
sfSapply(1:8,function(j)Sys.sleep(8))
\$\endgroup\$
7
  • \$\begingroup\$ Hello, and welcome to PPCG! This is code-golf so you must include your byte count. If you accept my edit, you don't have to worry about it. \$\endgroup\$ Commented Jun 17, 2016 at 16:15
  • \$\begingroup\$ You also need to include in your header Snowfall. \$\endgroup\$ Commented Jun 17, 2016 at 16:26
  • \$\begingroup\$ How does the output look? \$\endgroup\$
    – Adám
    Commented Jun 17, 2016 at 16:51
  • \$\begingroup\$ What is a "UTF-8 byte"? \$\endgroup\$
    – Adám
    Commented Jun 17, 2016 at 19:21
  • 3
    \$\begingroup\$ @Adám: The byte counting userscript I use says "Winner: JDL's answer at -8 bytes". \$\endgroup\$ Commented Jul 2, 2016 at 14:52
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.