Warten Sie eine Minute - in weniger als zehn Sekunden


69

Aufgabe

Warten Sie bei jeder Art von Parallelisierung mehrere Perioden, bis eine Gesamtruhezeit von mindestens einer Minute (jedoch weniger als eineinhalb Minuten) erreicht ist.

Das Programm / die Funktion muss innerhalb von 10 Sekunden beendet werden und (auf irgendeine Weise und in irgendeinem Format) zwei Werte zurückgeben: die gesamte verstrichene Zeit und die gesamte ausgeführte Ruhezeit. Beide Zeitwerte müssen eine Genauigkeit von mindestens 0,1 Sekunden haben.

Dies ähnelt dem Konzept der Arbeitszeit : Ein Job, der 60 Stunden dauert, kann in nur 6 Stunden erledigt werden, wenn 10 Arbeiter den Job aufteilen. Hier können wir 60 Sekunden Ruhezeit haben, z. B. in 10 parallelen Threads, sodass nur 6 Sekunden erforderlich sind, um den gesamten Job abzuschließen.

Beispiel

Das Programm MyProgram erzeugt 14 Threads, jeder Thread schläft 5 Sekunden lang:

MyProgram[5.016,70.105]

Die Ausführungszeit ist länger als 5 Sekunden, und die Gesamtruhezeit ist wegen des Overheads länger als 70 Sekunden.


2
Ich habe die Frage mehrmals gelesen und verstehe sie nicht. Können Sie etwas klarstellen? Warum "10 Sekunden" und eine Verzögerung von "70 Sekunden"? Wie hängen all diese Zeiten zusammen?
Luis Mendo

3
Wie viele Threads werden voraussichtlich parallel ausgeführt?
Meilen

3
Welche Genauigkeit ist für die Ausgabezeit erforderlich?
edc65

20
Ich frage mich, ob dies dazu führen wird, dass sich alle Autoren der Golfsprache auf einen wahnsinnigen Schachzug einlassen, um ihren Kreationen Multithreading zu verleihen ...
Adám,

3
@NoOneIsHere Nun, eine ordnungsgemäß implementierte Schlafmethode sollte keinen Kern belegen, daher kann die Anzahl der Threads die Anzahl der (virtuellen) Prozessoren überschreiten.
Adám

Antworten:


15

Dyalog APL, 65 27 23 21 Bytes

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

Dh:

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

Erläuterung:

  • ⎕DL&¨9/7: 9 Fäden abspinnen, die jeweils 7 Sekunden warten. ⎕DLGibt die tatsächliche Wartezeit in Sekunden zurück, die dem Argument entspricht, das einige Millisekunden dauert oder gibt.
  • ⎕TSYNC: Warten Sie, bis alle Threads abgeschlossen sind, und rufen Sie das Ergebnis für jeden Thread ab.
  • (⌈/,+/): gibt die längste Ausführungszeit eines einzelnen Threads zurück (während dessen Ausführung alle anderen Threads beendet wurden, dies ist also die tatsächliche Laufzeit), gefolgt von der Summe der Ausführungszeit aller Threads.

Probieren Sie es online!


Dies funktioniert nicht, wenn es um 23:59:57 Uhr ausgeführt wird. Sie sind jedoch auf dem richtigen Weg ... Können Sie, während Sie bereits die kürzesten sind, weitere 40 Bytes weggolfen?
Adám

1
@Adam: nein, aber ich kann 38 Bytes weggolfen. Es ist ganz offensichtlich, ich weiß nicht, warum ich das erste Mal nicht daran gedacht habe.
Marinus

Es geht los. Nur noch 6 Bytes, bis Sie ein Häkchen bekommen. Die drei Dinge, die Sie tun müssen, liegen auf der Hand und sparen jeweils 1, 2 und 3 Byte.
Adám

Sehr schön, Sie fanden Nummer 1 und Nummer 3. Nummer 2 ist nicht wirklich Golf, so viel wie eine Implementierungsalternative ...
Adám

Nummer 2: Da Sie keine Argumente benötigen, machen Sie es einfach zu einem tfn-Body.
Adám

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

Dies erfordert ein Betriebssystem mit einer Zeitgenauigkeit von mehr als 1 Sekunde, um ordnungsgemäß zu funktionieren (mit anderen Worten, jedes moderne Betriebssystem). Es werden 8 Threads erstellt, die jeweils 9 Sekunden lang schlafen, was zu einer Echtzeit-Laufzeit von ~ 9 Sekunden und einer parallelen Laufzeit von ~ 72 Sekunden führt.

Obwohl die offizielle Dokumentation besagt, dass der ThreadKonstruktor mit Schlüsselwortargumenten aufgerufen werden sollte, bin ich vorsichtig und verwende ohnehin Positionsargumente. Das erste Argument ( group) muss sein None, und das zweite Argument ist die Zielfunktion.

nneonneo wies in den Kommentaren darauf hin, dass der Attributzugriff (zB f.t) kürzer ist als der Listenindexzugriff (zB t[0]). Leider gehen in den meisten Fällen die wenigen dabei gewonnenen Bytes verloren, wenn ein Objekt erstellt werden muss, mit dem benutzerdefinierte Attribute zur Laufzeit erstellt werden können. Zum Glück unterstützen Funktionen benutzerdefinierte Attribute zur Laufzeit. Daher nutze ich dies aus, indem ich die Gesamtzeit im tAttribut von speichere f.

Probieren Sie es online aus

Danke an DenkerAffe für -5 Bytes mit dem execTrick.

Vielen Dank an kundor für -7 Bytes, der darauf hingewiesen hat, dass das Thread-Argument nicht erforderlich ist.

Danke an nneonneo für -7 Bytes aus diversen Verbesserungen.


Sie können zwei Bytes sparen, indem Sie das Argument bis f()und die letzten beiden Argumente bis Threadentfernen (wodurch 7 Zeichen entfernt werden) und die Verwendung von t.append(m()-n), um die Zuweisung einer lokalen Variablen zu vermeiden t(5 Zeichen mehr als +=.)
Nick Matteo

Und Sie können fünf weitere sparen, indem Sie die Summe anstelle einer Liste von Malen beibehalten: Initialisieren tmit t=[0], Anhängen durch t[0]+=m()-nund Ersetzen sum(t)durch t[0].
Nick Matteo

Threadnamen können weggelassen werden.
Paprika

@ppperry: nicht, wenn Sie die nachfolgenden Positionsargumente verwenden müssen (aber wie ich in früheren Kommentaren erwähnt habe, können Sie diese tatsächlich beseitigen.)
Nick Matteo

Sparen Sie drei Bytes mit import threading as H,time as t; Speichern Sie weitere zwei Bytes mit z=H.Threadund map(z.join,r). Speichern Sie weitere zwei Bytes, indem Sie die Gesamtzeit als Attribut T.z+=m()-n
speichern

11

Bash + GNU-Dienstprogramme, 85

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

timeErzwingt die Verwendung der ausführbaren Datei anstelle der eingebauten Shell, indem ein vorangestellt wird \.

Hängt an eine Datei an j, die zu Beginn leer oder nicht vorhanden sein muss.


Wie wäre es mit einem Forking-Skript? if [ $1 -lt 9 ];then { ./a $(( $1 + 1 )) &};sleep 7;fioder so? Wäre das gegen die Regeln oder etwas, was ich über die Spezifikation nicht verstehe? [bearbeiten; Ich habe die Anforderung für die Ausgabe verpasst. Oh, das macht es interessant!]
Dewi Morgan

1
@DewiMorgan Ja, die Ausgabeanforderung macht es ein bisschen schwieriger. Was Sie vorschlagen, könnte zu etwas wie Golf gespielt werden(($1<9))&&$0 $[$1+1]&sleep 7
Digital Trauma

9

Go - 189 Bytes

Vielen Dank @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)}

Ausgänge (ms): 160,9939 ms , 60001 ms (160 ms , um 60,001 Sekunden zu warten)


1
Hallo und willkommen bei PPCG! Dieser Kommentar @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.bedeutet nicht, dass Sie nicht versuchen sollten , Ihre Antwort auf Golf zu spielen, aber dass es in Ordnung ist, wenn es nicht gewinnt. Können Sie bitte eine Golf-Lösung hinzufügen?
NoOneIsHere

Es tut mir leid, ich habe gerade deine Bearbeitung gelesen. Für Golfer könnten Sie vielleicht Zeilenumbrüche und Leerzeichen entfernen oder totzu etwas ähnlichem wechseln q.
NoOneIsHere

@NoOneIsHere, danke dafür, ich hatte diese Variable komplett übersehen! Auch schlug m und t zusammen.
Rob



8

Bash 196 117 114 93 Bytes

Aktualisiert, um eine bessere Zeitgenauigkeit zu unterstützen, indem Vorschläge von @manatwork und @Digital Trauma sowie einige andere Raumoptimierungen integriert werden:

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

Beachten Sie, dass dies voraussetzt, dass die jDatei am Anfang nicht vorhanden ist.


2
function ss(), b=`date +%s`b=$SECONDS, expr $t + $i$[t+i], `cat j`$(<j)und in der Regel sehen Tipps für in Bash Golf spielen , wie es zu dieser reduzieren: pastebin.com/DDqUaDug
Manatwork

Um es weiter zu reduzieren, schreiben Sie besser direkt eine Formel in die Datei j. Ich meine statt 5↵5↵5↵…schreiben +5+5+5…- dann laden alle direkt in die Arithmetik Auswertung und verschonen die zweite Schleife: pastebin.com/LB0BjDMZ
Manatwork

Da die Mindestgenauigkeit später angegeben wurde, vergessen Sie den b=`date +%s`b=$SECONDSVorschlag.
Manatwork

1
Wie bashbei der Ganzzahlarithmetik muss die gesamte Lösung neu geschrieben werden, um ein externes Tool für die Berechnung zu verwenden. Typisch bc: pastebin.com/eYFEVUuz
Manatwork

1
@ JuliePelletier Ok, ich poste es als meine eigene Antwort. Dennoch denke ich, dass Sie einige der Golftechniken auf Ihre Antwort anwenden können, ohne den Ansatz wesentlich zu ändern: pastebin.com/ssYzVs1n (93 Bytes)
Digitales Trauma

8

JavaScript (ES6), 148 Byte

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]));

Verspricht, 9 Mal 7 Sekunden lang insgesamt 63 Sekunden zu warten (tatsächlich 63,43, wenn ich es versuche), aber tatsächlich dauert es nur 7,05 Sekunden in Echtzeit, wenn ich es versuche.


8

C, 127 Bytes (dreht die CPU)

Diese Lösung dreht die CPU, anstatt zu schlafen, und zählt die Zeit mithilfe der timesPOSIX-Funktion (die die CPU-Zeit misst, die vom übergeordneten Prozess und in allen auf Kinder wartenden Prozessen verbraucht wird).

Es gibt 7 Prozesse aus, die sich jeweils 9 Sekunden lang drehen, und gibt die Endzeiten in C-Takten aus (bei den meisten Systemen sind 100 Takten = 1 Sekunde).

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]));}

Beispielausgabe:

906,6347

Das bedeutet 9,06 Sekunden Echtzeit und 63,47 Sekunden Gesamt-CPU-Zeit.

Für beste Ergebnisse kompilieren Sie mit -std=c90 -m32(erzwingen Sie 32-Bit-Code auf einem 64-Bit-Computer).


5

PowerShell v4, 144 Byte

$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 $dgleich zu Get-Dateund löscht alle vorhandenen Auftragsprotokolle mit Get-Job | Remove-Job. Wir durchlaufen dann eine Schleife 1..20|%{...}und führen bei jeder Iteration Start-Jobden Skriptblock {$x=date;sleep 3;((date)-$x).ticks/1e7}für den Job aus (dh, jeder Job führt diesen Skriptblock aus). Wir leiten diese Ausgabe an weiter >$null, um das zurückgegebene Feedback (dh Jobname, Status usw.) zu unterdrücken.

Der Skriptblock setzt $xauf Get-Date, dann Start-Sleepfür 3Sekunden, nimmt dann eine neue Get-DateLesung vor, subtrahiert $x, erhält die .Ticksund dividiert durch 1e7, um die Sekunden zu erhalten (mit Genauigkeit).

Zurück im Hauptthread -Sdrehen "Running"wir uns in einer leeren whileSchleife , solange ein Job noch erledigt ist . Sobald dies erledigt ist, rufen wir Get-JobObjekte für alle vorhandenen Jobs auf, Receive-Jobleiten diejenigen, an die STDOUT (dh was sie ausgeben), -joindie Ergebnisse zusammen mit STDOUT und leiten +sie an iex( Invoke-Expressionund ähnlich eval). Dies gibt die resultierende Ruhezeit plus Overhead aus.

Die letzte Zeile ist insofern ähnlich, als sie ein neues Datum erhält, den ursprünglichen Datumsstempel subtrahiert $d, den abruft .Ticksund durch dividiert, um 1e7die Gesamtausführungszeit auszugeben.


NB

OK, das ist also ein bisschen krumm von den Regeln. Anscheinend muss PowerShell bei der ersten Ausführung eine Reihe von .NET-Assemblys für die verschiedenen Thread-Vorgänge von der Festplatte laden, da sie nicht mit dem Standard-Shell-Profil geladen werden. Nachfolgende Ausführungen funktionieren einwandfrei, da sich die Assemblys bereits im Speicher befinden. Wenn Sie das Shell-Fenster lange genug im Leerlauf lassen, kann die integrierte Garbage Collection von PowerShell alle diese Assemblys entladen. Dies führt dazu, dass die nächste Ausführung beim erneuten Laden sehr lange dauert. Ich bin mir nicht sicher, wie ich das umgehen soll.

Sie können dies an den Ausführungszeiten in den folgenden Läufen ablesen. Ich startete eine neue Shell, navigierte zu meinem Golfverzeichnis und führte das Skript aus. Der erste Lauf war schrecklich, aber der zweite (sofort ausgeführt) hat gut funktioniert. Dann ließ ich die Shell einige Minuten im Leerlauf, damit die Garbage Collection vorbeikam, und dann ist dieser Lauf wieder langwierig, aber nachfolgende Läufe funktionieren wieder einwandfrei.

Beispiel läuft

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>

1
Ich werde sagen, das ist in Ordnung. :-)
Adám

5

Javascript (ES6), 212 203 145 Bytes

Mit diesem Code werden beim Laden 10 Bilder mit einem Zeitintervall von jeweils genau 6 Sekunden erstellt.

Die Ausführungszeit ist geringfügig länger (aufgrund von Overhead).

Dieser Code überschreibt alles im Dokument!

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)

Dies setzt voraus, dass Sie für die Backticks eine Einzelbyte-Codierung verwenden, die erforderlich ist, damit die Javascript-Engine nicht auslöst.


Alternativ, wenn Sie nicht 6 Sekunden warten möchten, finden Sie hier eine 1 Byte längere Lösung, die in weniger als einer Sekunde abgeschlossen ist:

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)

Der Unterschied besteht darin, dass dieser Code 600 ms auf 100 Bilder wartet. Dies führt zu einem enormen Overhead.


Alte Version (203 Bytes):

Dieser Code erstellt 10 Iframes mit einem Zeitintervall von jeweils genau 6 Sekunden, anstatt 10 Bilder zu erstellen.

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)


Originalversion (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)})


2
+1 Sehr schöne und andere Herangehensweise. Was würde in einem Singlethread-Browser passieren?
Adám

2
@ Adám Keine Verhaltensänderung. Es würde immer noch eine Verzögerung von ungefähr 6 Sekunden geben. Firefox (ein Single-Thread-Browser) gibt manchmal witzige Dinge aus, beispielsweise eine Ausführungszeit von 59999. <something>.
Ismael Miguel

4

Rubin, 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

4

Javascript (ES6), 108 92 Bytes

Ich mache eine neue Antwort, da dies einen etwas anderen Ansatz verwendet.

Es erzeugt eine setTimeoutenorme Menge von s, die fast alle mit 4 ms Abstand ausgeführt werden.

Jedes Intervall beträgt 610 Millisekunden über insgesamt 99 Intervalle.

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

Es läuft normalerweise innerhalb von 610 ms, was einer Gesamtausführungszeit von etwa 60,5 Sekunden entspricht.

Dies wurde auf Google Chrome Version 51.0.2704.84 m unter Windows 8.1 x64 getestet.


Alte 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))


4

Scratch - 164 Bytes (16 Blöcke)

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

Visuelles Skript

Sehen sie in Aktion hier .

Verwendet eine Variable mit dem Namen 't' und ein Sprite mit dem Namen 's'. Das Sprite erstellt Klone von sich selbst, von denen jeder 8 Sekunden wartet, und erhöht eine Variable, die die gesamte Wartezeit taktet. Am Ende steht die gesamte Ausführungszeit und die gesamte Wartezeit (zum Beispiel 65.488 8.302).


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)])

Formatierte Version mit benannten Variablen:

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

Ausgabe (in Nanosekunden):

[62999772966 7001137032]

Geändertes Format. Vielen Dank, Adám. Möglicherweise habe ich diese Formatangabe in der Frage beim Lesen übersehen.

Geändert zu nanoTime für Golffähigkeiten.

Dank Cliffroot habe ich die wissenschaftliche Notation völlig vergessen und kann nicht glauben, dass ich sie nicht gesehen habe apply. Ich glaube, ich habe das in etwas benutzt, was ich gestern golfen, aber nie gepostet habe. Du hast mir 2 Bytes gerettet.


Willkommen bei PPCG! Schöner erster Beitrag! Möglicherweise können Sie das OP nach dem Ausgabeformat fragen.
17.

Keine Notwendigkeit umzukehren. OP: mit allen Mitteln und in jedem Format .
Adám

Anscheinend können Sie 7e3anstelle von 7000und applyanstelle von verwendenreduce
Cliffroot

3

Rust, 257 , 247 Bytes

Ich benutze das gleiche mal wie Megos Python-Antwort.

Wirklich ist das einzige etwas kluge Bit, ii zu verwenden, um eine Dauer von 0 Sekunden zu erhalten.

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());}

Drucke:

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: Gute alte Schleife ist etwas kürzer


3

JavaScript (ES6, mit 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: Die Art und Weise, wie ein Worker aus einer Zeichenfolge ausgeführt wird, wurde im Hinblick auf ursprungsübergreifende Richtlinien durch eine kompaktere und browserübergreifendere ersetzt. Funktioniert nicht in Safari, wenn das webkitURLObjekt noch vorhanden ist URL, und im IE.


1
Ich { "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 }
erhalte

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

Dies ist eine Herleitung von Megos Antwort, aber es ist ausreichend anders, dass ich dachte, es sollte eine separate Antwort sein. Es wurde getestet, um unter Windows zu funktionieren.

Grundsätzlich werden 9 Threads abgezweigt, die 7 Sekunden lang schlafen, während die Eltern 8 Sekunden lang schlafen. Anschließend werden die Zeiten ausgedruckt. Beispielausgabe:

8.00059192923 71.0259046024

Misst unter Windows time.clockdie Wandzeit seit dem ersten Aufruf.


Es ist wichtig zu beachten, dass dies nur unter Windows funktioniert und time.clock()sich zwischen Windows- und UNIX / Linux-Plattformen unterschiedlich verhält .
Mego

3

Perl 6, 72 71 Bytes

Möglicherweise gibt es dafür einen kürzeren Weg

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

diese Ausgänge

63.00660729694
7.0064013

2

Mathematica, 109 Bytes

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

Anonyme Funktion. Erfordert eine Lizenz mit mehr als 7 Unterkernen. Nimmt 9 Sekunden Echtzeit und 63 Sekunden Kernel-Zeit in Anspruch, ohne den Overhead zu berücksichtigen. Stellen Sie sicher, dass Sie die vorhergehenden Anweisungen nur einmal ausführen (damit der Kernel nicht neu gestartet wird). Testen:

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}

2
Überlassen Sie es Wolfram, die Lizenzbeschränkungen für das Verzweigen eines untergeordneten Prozesses festzulegen.
Mario Carneiro

2

Javascript (ES6), 105 Byte

((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)

Aktualisierte Version: 106 Bytes Entliehen von @Ismael Miguel, da er die großartige Idee hatte, die Schlafzeit zu verkürzen und die Intervalle zu erhöhen.

((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)


2
Stattdessen d+=t()-s;if(!c)alert([t()-i,d])können Sie schreiben d+=t()-s;c||alert([t()-i,d]), wodurch einige Bytes gespart werden. Auch, wenn Sie die Funktion entfernen und neu zu schreiben alles, können Sie mit meiner 92-Byte langen Lösung konkurrieren: for(c=8,i=(t=Date.now)(d=0);c--;)setTimeout((c,s)=>{d+=t()-s;c||alert([t()-i,d])},8e3,c,t()). Und ja, dieser ist auch 92 Bytes lang.
Ismael Miguel

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);}}

und 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);
    }
}

Bitte versuchen Sie es nicht zu Hause, da diese Lösung nicht threadsicher ist.

Bearbeiten:

Ich habe die Vorschläge von @A Boschman und @ Adám aufgegriffen, und jetzt dauert die Ausführung meines Programms weniger als 10 Sekunden, und es ist um 15 Byte kürzer.


2
Sie befinden sich in einem untergeordneten Element der Thread-Klasse. Können Sie die Thread.Aufrufe der Methode at the static sleep () nicht auslassen ? Wird dieses Programm nicht in etwas mehr als 10 Sekunden beendet und disqualifiziert?
Ein Boschman

@ABoschman danke für den Vorschlag, und es ist jetzt behoben, es läuft nicht mehr als 10 Sekunden
user902383

1
Vergessen Sie auch nicht, dass wir eine große Auswahl an Tipps für das Golfen in Java haben :)
Katenkyo

1
Dies scheint anfällig für Race-Bedingungen zum Lesen, Ändern und Schreiben zu sein. Sie haben keine Art von Sperre oder irgendetwas in Ihrer Nähe static long t. Ich erwähne dies nur, weil in der Spezifikation steht "Beide Zeitwerte müssen eine Genauigkeit von mindestens 0,1 Sekunden haben."
Poke

1
Sie können die entfernen , long bevor das sund fügen Sie ,szu der static long t,i,s;ein paar Bytes zu speichern.
Kevin Cruijssen

2

C (mit 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);}

2

C90 (OpenMP), 131 Bytes (+ 17 für Umgebungsvariable) = 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);}

Beispielausgabe:

7091,9.000014

Anmerkungen:

7091 erfolgt in Zyklen (100 / Sek.), Daher wurde das Programm 70 Sekunden lang ausgeführt

Könnte viel kürzer sein, wenn ich einen Weg finden würde, einen Timer außer omp_get_wtime () zum Laufen zu bringen, da ich dann auch die include-Anweisung entfernen könnte.

Führen Sie mit OMP_NUM_THREADS = 9 aus


Sie können die Umgebungsvariable einrichten, müssen dazu jedoch die Bytes zählen, es sei denn, die von Ihnen gewählte Einstellung ist eine übliche Standardeinstellung.
Adám

@ Adám Danke, das habe ich mir gedacht, es spart 6 oder 7 Bytes
dj0wns

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)))))

Dies erzeugt nur Threads, die sich im Ruhezustand befinden, und erhöht dann die benötigte Zeit auf atomare Weise. Dabei dreht sich eine äußere Schleife, die darauf wartet, dass die Gesamtzeit mehr als 60000 Ticks beträgt (dh 60s auf sbcl). Der Zähler wird in einer Liste gespeichert, da die Art der Orte, die atomic-incf ändern kann, begrenzt ist. Möglicherweise ist nicht genügend Speicherplatz vorhanden, bevor das Programm auf schnelleren Computern beendet wird.

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)))))

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

Gabelt 7 untergeordnete Prozesse, von denen jeder 9 Sekunden wartet.

Beispielausgabe:

perl wait-one-minute.pl
9.00925707817078-63.001741

1

Groovy, 158 143 Zeichen

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])}

Probelauf:

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

1

Elixier, 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)

Probelauf:

$ elixir thing.exs
64012846
4007547

Die Ausgabe ist die Gesamtwartezeit, gefolgt von der Laufzeit des Programms in Mikrosekunden.

Das Programm erzeugt 14 TaskSekunden und wartet auf jeden von ihnen, indem es sie abbildet, und ermittelt dann die Summe ihrer verstrichenen Zeit. Es verwendet Erlang's timerzum Messen der Zeit.


Willkommen in der Community !!
Erik der Outgolfer

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

!misst die von der Aktion benötigte Zeit a(zweites Argument) und bezieht sich b(erstes Argument) auf das Ergebnis.

w ist die Schlaffunktion.

mainwird selbst gemessen und das Ergebnis gedruckt ( print!...).

#ist replicateM, die gegebene Aktion N-mal zu wiederholen (und twegen Golf zurückzukehren).

Innerhalb des gemessenen Teils replicate 9 $ forkIO ...schlafen 9 Threads ( ) für 5^10Millisekunden (9,765625 Sekunden) und veröffentlichen das Ergebnis ( writeChan) in einer vom Haupt-Thread ( newChan) erstellten Pipe , die die 9 Ergebnisse summiert und die Summe ( getChanContents >>= print . sum . take 9) ausgibt .

Ausgabe:

87.938546708s
9.772032144s

1
@ Adám 6 ^ 9> 10 ^ 7 (10 Sekunden).
Koterpillar

1

Python 2, 132 Bytes

Verwendet einen Prozesspool, um 9 Prozesse zu erzeugen und jeden für 7 Sekunden schlafen zu lassen.

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

Gibt zuerst die gesamte akkumulierte Schlafzeit und dann die tatsächliche Laufzeit aus:

$ python test.py
63.0631158352 7.04391384125

1

Rubin (mit parallelEdelstein), 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

Bearbeiten: Der "Time.now" -Referenz aus der Ruby-Antwort von Histocrat wurde hinzugefügt.


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]

Schnelle Erklärung: parforErstellt eine parallele for-Schleife, die über den Pool von Arbeitnehmern verteilt ist. ticund tocdie verstrichene Zeit messen (und sind meiner Meinung nach eine der am besten benannten Funktionen in MATLAB). Die letzte Zeile (ein Array mit der Gesamtschlafzeit und der verstrichenen Echtzeit) wird ausgegeben, da sie nicht mit einem Semikolon abgeschlossen wird.

Beachten Sie jedoch, dass dies 9 vollwertige MATLAB-Prozesse erzeugt. Es besteht dann die Möglichkeit, dass dieses bestimmte Programm nicht innerhalb der auf Ihrem Computer zugewiesenen 10 Sekunden beendet wird. Ich denke jedoch, dass bei einer MATLAB-Installation, bei der außer der auf einem High-End-System mit SSD installierten Parallel Computing-Toolbox keine Toolboxes installiert sind, die Installation möglicherweise nur innerhalb von 10 Sekunden abgeschlossen werden kann. Bei Bedarf können Sie die Parameter optimieren, damit weniger Prozesse mehr schlafen.


Der Fehler bliegt wahrscheinlich nur daran, dass Sie bereits etwas in Ihrem Arbeitsbereich hatten. Ich habe keine Probleme mit 2015bparfor q=b
Suever

@Suever Oh hey, ich hatte ein Skript namens bm in meinem MATLAB-Ordner.
Sanchises
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.