PS./.NET performance

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Ja, ik weet het, PowerShell hoort om een of andere bizarre reden eigenlijk in Windows Clients thuis en niet in Programming; maar: het gaat hier minder over PS dan over .NET classes.

Situatie: een bepaalde functie die ik schreef expand IP adressen in de CIDR notatie (dus bv. 192.168.0.1/24 naar alle mogelijke adressen). Voor sommige bewerkingen moet ik, met een hoop opzoekingswerk, naar.NET grijpen, zoals [System.Net.IPAddress]::Parse($foo) waarbij $foo een decimaal adres is.

Een collega maakte eerder een gelijkaardige functie in VBS, gebruik makend van dezelfde classes. In beide gevallen viel de performance best tegen: om 280 adressen te expanden heeft mijn machine één minuut nodig. Heeft iemand een theoretisch idee hoe dit kan komen? Mijn huidige vermoeden is dat de .NET classes de boel vertragen: dat is immers het enige dat onze scripts gemeen hebben naast het doel. 280 per minuut lijkt me voor een computer toch wel traag.

Wat al uitgesloten is:
- Read and Write op het netwerk vs. lokaal
- Alle adressen in één array en dan uitschrijven vs. line-per-line uitschrijven
- System resources: in het line-per-line geval wordt slechts 20% CPU gebruikt (en 70MB RAM). De machine zelf is een monster naar workstation normen trouwens.

Het doel van mijn thread is dus niet om code te krijgen - vandaar dat ik geen code post - maar wel wat theoretische gissingen waar de performance onder kan lijden.

In 't echt gaat het over enkele 10 000en adressen trouwens, vandaar de relevantie van de performance.

[ Voor 3% gewijzigd door YellowOnline op 27-07-2010 22:59 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Je weet dat een IP enkel een 'human readable' vorm van 4 bytes is? En als je dus alle adressen tussen 192.168.0.1 en 192.168.9.255 (3232235521 en 3232235775 resp.) wil hebben dat je dan dus gewoon kunt tellen? Ik zie even niet waarom je al die adressen 1 voor 1 zou willen parsen. Je hoeft alleen 't eerste IP te parsen en uit te puzzelen wat de suffix precies omvat.

[edit]
Of begrijp ik het begrip "expanden" zoal jij het nu bedoelt verkeerd?
YellowOnline schreef op dinsdag 27 juli 2010 @ 22:47:
Mijn huidige vermoeden is dat de .NET classes de boel vertragen
Aan een vermoeden heb je niks. Meten = weten. Maar to be honest geloof ik er maar weinig van dat het aan de .Net classes zou liggen.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Diagnostics;
using System.Net;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int c = 0; c < 255; c++)
                for (int d = 0; d <= 255; d++)
                    IPAddress.Parse(string.Format("192.168.{0}.{1}", c, d));

            Console.WriteLine(sw.Elapsed);
        }
    }
}

256 * 256 IP adressen parsen = 65.536 parse acties:
00:00:00.0734960

[ Voor 90% gewijzigd door RobIII op 28-07-2010 00:09 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je zult er gewoon een profiler tegen aan moeten gooien, want inderdaad zoals RobIII al zegt Meten = Weten.

Het is natuurlijk erg makkelijk om te meten hoe lang verschillende delen van je applicatie duren, je loopt dan snel genoeg tegen de bottleneck aan. Maar het lijkt mij logischer dat er een "fout" in je algoritme zit

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Coca-Cola
  • Registratie: Maart 2001
  • Laatst online: 03:50
Zonder je code te zien heeft het er alle schijn van dat jij in die minuut ook daadwerkelijk iets probeert te doen met die ip adressen, want gewoon parsen (zoals hierboven aangegeven) kost echt geen tijd. Weet je zeker dat je die ip adressen ook niet echt probeert te benaderen? (280 adressen / 60 sec ~= 4.5 ip / sec)

[ Voor 1% gewijzigd door Coca-Cola op 28-07-2010 09:36 . Reden: Pre coffee post ]


Acties:
  • 0 Henk 'm!

  • defcon84
  • Registratie: September 2009
  • Laatst online: 12-09 11:37

defcon84

Multipass?

Coca-Cola schreef op woensdag 28 juli 2010 @ 08:22:
Zonder je code te zien heeft het er alle schijn van dat jij in die miuut ook daadwerkelijk iets probeert te doen met die ip adressen, want gewoon parsen (zoals hierboven aangegeven) kost echt geen tijd. Weet je zeker dat je die ip adressen ook niet echt probeert te benaderen? (280 adressen / 60 sec ~= 4.5 sec / ip)
natuurlijk bedoel je ~= 4.5 ip / sec

:)

Acties:
  • 0 Henk 'm!

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Coca-Cola schreef op woensdag 28 juli 2010 @ 08:22:
Zonder je code te zien heeft het er alle schijn van dat jij in die miuut ook daadwerkelijk iets probeert te doen met die ip adressen, want gewoon parsen (zoals hierboven aangegeven) kost echt geen tijd. Weet je zeker dat je die ip adressen ook niet echt probeert te benaderen? (280 adressen / 60 sec ~= 4.5 sec / ip)
Wat de code, samengevat, doet is dit:

- address/cidr splitsen in $address en $cidr
- address wordt omgezet naar decimaal
- alle mogelijke decimale adressen worden gegenereerd
- de decimale adressen worden geparsed met eerdervermelde class
- append naar een tekstbestand
bv. 192.168.0.1/30 -> IP0001.txt met daarin, per lijn, 192.168.0.1 en 192.168.0.2

Er wordt dus nergens een poging gedaan om die adressen te benaderen.

De uitleg van RobIII bekijk ik als ik wat wakkerder ben - ik denk dat we niet helemaal over hetzelfde spreken op 't eerste zicht.

Acties:
  • 0 Henk 'm!

  • defcon84
  • Registratie: September 2009
  • Laatst online: 12-09 11:37

defcon84

Multipass?

dus jij zet bvb 192.168.0.0/22 om naar de 1024 adressen (192.168.0.0 tot 192.168.3.255) en schrijft deze weg naar een txt bestandje..
de omzetting duurt normaal maar een fractie van een seconde, dus lijkt me dat je iets fout doet bij het wegschrijven naar het bestandje.
als je dat gedeelte eens weglaat (comment) in je code, en dan nog eens runt, hoelang duurt het dan?
mss open en sluit je je bestandje elke regel opnieuw, eventueel heb je daar ook een memory leak..

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
YellowOnline schreef op woensdag 28 juli 2010 @ 09:18:
[...]


Wat de code, samengevat, doet is dit:

- address/cidr splitsen in $address en $cidr
- address wordt omgezet naar decimaal
- alle mogelijke decimale adressen worden gegenereerd
- de decimale adressen worden geparsed met eerdervermelde class
- append naar een tekstbestand
bv. 192.168.0.1/30 -> IP0001.txt met daarin, per lijn, 192.168.0.1 en 192.168.0.2

Er wordt dus nergens een poging gedaan om die adressen te benaderen.

De uitleg van RobIII bekijk ik als ik wat wakkerder ben - ik denk dat we niet helemaal over hetzelfde spreken op 't eerste zicht.
Zonder dat je concreet bekijkt waar de bottleneck zit kunnen we helemaal niks om je te helpen. Zeker niet als er ook nog eens geen relevante code van de bottleneck bij staat.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
defcon84 schreef op woensdag 28 juli 2010 @ 09:23:
dus jij zet bvb 192.168.0.0/22 om naar de 1024 adressen (192.168.0.0 tot 192.168.3.255) en schrijft deze weg naar een txt bestandje..
de omzetting duurt normaal maar een fractie van een seconde, dus lijkt me dat je iets fout doet bij het wegschrijven naar het bestandje.
als je dat gedeelte eens weglaat (comment) in je code, en dan nog eens runt, hoelang duurt het dan?
mss open en sluit je je bestandje elke regel opnieuw, eventueel heb je daar ook een memory leak..
Het probleem lijkt inderdaad daar te liggen en niets te maken te hebben met de expand. Als ik niet wegschrijf naar een bestand gaat het zo'n 100x sneller.

Sorry, .NET, dat ik je ten onrechte beschuldigde :9

Acties:
  • 0 Henk 'm!

  • Coca-Cola
  • Registratie: Maart 2001
  • Laatst online: 03:50
YellowOnline schreef op woensdag 28 juli 2010 @ 10:07:
[...]


Het probleem lijkt inderdaad daar te liggen en niets te maken te hebben met de expand. Als ik niet wegschrijf naar een bestand gaat het zo'n 100x sneller.

Sorry, .NET, dat ik je ten onrechte beschuldigde :9
Open je soms voor elke schrijf actie het bestand opnieuw en doe je dan een append om vervolgens het bestand weer te sluiten?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Coca-Cola schreef op woensdag 28 juli 2010 @ 10:25:
[...]


Open je soms voor elke schrijf actie het bestand opnieuw en doe je dan een append om vervolgens het bestand weer te sluiten?
Daar riekt het wel naar. Maar wat TS moet gaan doen is profilen, meten. Alleen dan kan hier nog iets zinnigs uit komen.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Coca-Cola schreef op woensdag 28 juli 2010 @ 10:25:
[...]


Open je soms voor elke schrijf actie het bestand opnieuw en doe je dan een append om vervolgens het bestand weer te sluiten?
Helaas ja, omdat ik het aantal lijnen per bestand moet beperken en niet meteen een betere oplossing wist.

Op het risico als neo-scripter gelyncht te worden door de doorgewinterde devvers hier een fragment code:

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$fileCount = 1

ForEach ($objIPs in $arrIPs)
    {
    # Bestandsnaam wordt gegenereerd, syntax <pad>\IP####.txt
    $target = "{0}\IP{1:d4}.txt" -f $outputPath, $fileCount 
    
    # Kleine controle of de huidige bestandsnaam al bestaat
    $fileExists = Test-Path $target 
    
    # Indien bestand al bestaat: steek het aantal lijnen in een variabele
    If ($fileExists -EQ $true) {$targetSize = Get-Content $target | Measure-Object -Line}
    
    # Schrijf elk IP adres naar het bestand
    $objIPs.IPAddressToString | Out-File -FilePath $target -Append -Encoding ASCII
    
    # Blijkt het aantal lijnen een op voorhand opgegeven maximum te overstijgen,
    # dan wordt het getal in de bestandsnaam +1 gedaan.
    If ($targetSize.Lines -GE ($outputSize-1)){$targetSize = 0; $fileCount++}
    }


(T.net heeft nog geen PS syntax highlighting)

Ik ben al aan een oplossing bezig: m'n output wordt per adres/cidr naar één textbestand gestuurd dat ik achteraf in stukjes knip. Zo open ik maar 1000 keer een bestand ipv. pakweg 100 000 keer. Alles naar één array sturen is geen optie gezien zo'n array gigantisch zou worden (het gaat over 10 000en adressen hé).

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
YellowOnline schreef op woensdag 28 juli 2010 @ 10:58:
Alles naar één array sturen is geen optie gezien zo'n array gigantisch zou worden (het gaat over 10 000en adressen hé).
:D Heb je dat nou al eens geprobeerd / gemeten / uitgerekend? Stel dat je 100.000 adressen hebt, a 4 bytes. Dat kost je 100.000 x 4 = 400.000 bytes ~= 391k. Poehee. Ik denk dat de gemiddelde PC daar wel moeite mee heeft ja :X :P
Je zult nog wel wat overhead hebben op de array etc. maar als je nou eens even nadenkt voor je dat soort uitspraken doet dan bespaar je jezelf idd een lynchpartij ;)

[ Voor 16% gewijzigd door RobIII op 28-07-2010 11:04 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Kan je niet beter RobIII's basiscode in C# gebruiken? Dat debugged ook nog eens makkelijker, naast dat het waarschijnlijk veel sneller gaat zijn dan dat PS script. En een Console app in C# is natuurlijk ook prima te gebruiken in de console :P , voor scheduling ed.

Sundown Circus


Acties:
  • 0 Henk 'm!

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
RobIII schreef op woensdag 28 juli 2010 @ 11:02:
[...]

:D Heb je dat nou al eens geprobeerd / gemeten / uitgerekend? Stel dat je 100.000 adressen hebt, a 4 bytes. Dat kost je 100.000 x 4 = 400.000 bytes ~= 391k. Poehee. Ik denk dat de gemiddelde PC daar wel moeite mee heeft ja :X :P
Je zult nog wel wat overhead hebben op de array etc. maar als je nou eens even nadenkt voor je dat soort uitspraken doet dan bespaar je jezelf idd een lynchpartij ;)
Ik had dat gedaan in mijn eerste script, maar halverwege gebruikte mijn shell al 1.5GB aan RAM, itt. het laatste script dat maar 22MB gebruikt. De werkelijke data is 200B trouwens ipv. 4B - maar dat verklaart nog steeds het geheugengebruik niet.

Nou, ik weet in ieder geval waar het probleem zat en kan nu verder aan de slag. Waarvoor mijn dank.

Acties:
  • 0 Henk 'm!

  • defcon84
  • Registratie: September 2009
  • Laatst online: 12-09 11:37

defcon84

Multipass?

graag gedaan & veel succes :)

Acties:
  • 0 Henk 'm!

  • Meekoh
  • Registratie: April 2005
  • Laatst online: 16-09 16:34
YellowOnline schreef op woensdag 28 juli 2010 @ 11:23:
[...]


Ik had dat gedaan in mijn eerste script, maar halverwege gebruikte mijn shell al 1.5GB aan RAM, itt. het laatste script dat maar 22MB gebruikt. De werkelijke data is 200B trouwens ipv. 4B - maar dat verklaart nog steeds het geheugengebruik niet.

Nou, ik weet in ieder geval waar het probleem zat en kan nu verder aan de slag. Waarvoor mijn dank.
Dat komt vrij overeen met mijn ervaringen. Powershell is wanneer je niet goed al je objects weer closed, disposed etc. onwijs inefficiënt met zijn memory gebruik.
Wat mij nog het meest tegenvalt van PS is dat objecten pas gerecycled worden wanneer je je venstertje sluit.
Voorbeeld: ik run mijn PS Script-> Memory usage stijgt -> script is klaar -> Shell neem nog steeds veel mem ingebruik.
Hij geeft het gewoon niet weer vrij, voor het geval hij de objecten weer in dezelfde sessie nodig heeft.

Computer says no


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Meekoh schreef op woensdag 28 juli 2010 @ 17:12:
[...]
Hij geeft het gewoon niet weer vrij, voor het geval hij de objecten weer in dezelfde sessie nodig heeft.
Ik ben niet bekend met PowerShell, en weet dus ook niet in welke scope die objecten leven, maar zoals jij het aangeeft kan je die objecten later nog gebruiken. Het is dan logisch dat ze niet vrij gegeven worden. Een andere mogelijkheid is, is dat ze wel vrij gegeven zijn, maar dat het geheugen nog door het process geclaimed blijft. Dat is een vrij standaard iets van .NET. Pas op het moment dat het systeem geheugen te kort heeft word het weer vrij gegeven.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Woy schreef op woensdag 28 juli 2010 @ 19:16:
[...]

Ik ben niet bekend met PowerShell, en weet dus ook niet in welke scope die objecten leven, maar zoals jij het aangeeft kan je die objecten later nog gebruiken. Het is dan logisch dat ze niet vrij gegeven worden. Een andere mogelijkheid is, is dat ze wel vrij gegeven zijn, maar dat het geheugen nog door het process geclaimed blijft. Dat is een vrij standaard iets van .NET. Pas op het moment dat het systeem geheugen te kort heeft word het weer vrij gegeven.
Het is eerder zo. Tenzij expliciet als global gedefiniëerd zal een object steeds vrijgegeven worden eens de scope naar een parent overgaat.
Pagina: 1