Permalänk
Medlem

Loop hjälp C#

Hej!

Jag vill loopa igenom en array, räkna ut och returnera antal platser som är reserverade. Jag vill alltså kolla elementen i arrayen för att se om de är null eller empty. Men jag fattar inte riktigt hur jag ska lyckas med det

for(int index = 0; index < nameList.Length; index++)
{
Här vill jag alltså kolla vilka som är null elr empty men fattar inte riktigt hur jag kan göra det på ett smidigt sätt.
Typ if index is null or empty...
}

Tacksam för lite hjälp på vägen!

Permalänk
Medlem

Döp index till i istället, det är "standard"
Testa skriv typ if(nameList[i] == null) {

}

Permalänk
Medlem

typ en if sats i som kollar om indexplatsen den är på är 0/null?
Kan inte c# så borde det bli typ
if(index==0||null)
{
skriv ut index[]
}

Visa signatur

i7-6700K | MSI Z170A | MSI 1080 8GB | 16GB Kingston HyperX | Intel 600P 256GB | Samsung EVO Basic 840 250GB x2 raid 0 | Corsair RM 750W | 3 x Dell U2414H

Permalänk

for(int index = 0; index < nameList.Length; index++)
{
if(nameList[index] == null)
continue;

//do something
}

Permalänk
Keeper of Traditions
Skrivet av Shkipan:

Hej!

Jag vill loopa igenom en array, räkna ut och returnera antal platser som är reserverade. Jag vill alltså kolla elementen i arrayen för att se om de är null eller empty. Men jag fattar inte riktigt hur jag ska lyckas med det

for(int index = 0; index < nameList.Length; index++)
{
Här vill jag alltså kolla vilka som är null elr empty men fattar inte riktigt hur jag kan göra det på ett smidigt sätt.
Typ if index is null or empty...
}

Tacksam för lite hjälp på vägen!

När du säger "empty", menar du då null, eller menar du värdet noll?

For-loopen har du ju fått rätt, så det är bara att lägga in en if-sats.

int counter = 0; for(int index = 0; index < nameList.Length; index++) { if(nameList[index] != null) counter++; } return counter;

Visa signatur

|| Intel 8700K || Asus RTX 4070 TI Super TUF || Samsung 750 EVO 500GB & Kingston A2000 1TB & Samsung 960 EVO 250GB || Corsair RM 850x || Antec P183 || Asus G-Sync RoG Swift PG279Q || Dell XPS 15 || Thinkpad X220

The Force is like Duct Tape, it has a light side, a dark side, and holds the universe together.

Permalänk
Medlem

string[] arrayOne = {"a", null, "b", null, "c"}; for (int i = 0; i < arrayOne.Length; i++) { if (arrayOne[i] == null) { Console.WriteLine("Index {0} är null", i); } else { Console.WriteLine("Index {0} innehåller data.", i); }

Visa signatur

AW3423DW QD-OLED - Ryzen 5800x - MSI Gaming Trio X 3090 - 64GB 3600@cl16 - Samsung 980 Pro 2TB/WD Black SN850 2TB

Permalänk
Medlem
Skrivet av Newklear:

När du säger "empty", menar du då null, eller menar du värdet noll?

For-loopen har du ju fått rätt, så det är bara att lägga in en if-sats.

int counter = 0; for(int index = 0; index < nameList.Length; index++) { if(nameList[index] != null) counter++; } return counter;

Enligt uppgiften(läraren) så kunde man kolla mha String.IsNullOrEmpty, inget måste dock. Tack för all hjälp!! skall testa att komma vidare imorgon, dags att sova nu..

Permalänk
Keeper of Traditions
Skrivet av Shkipan:

Enligt uppgiften(läraren) så kunde man kolla mha String.IsNullOrEmpty, inget måste dock. Tack för all hjälp!! skall testa att komma vidare imorgon, dags att sova nu..

Jao, den kollar om strängen är null, tom eller om den innehåller något.

http://msdn.microsoft.com/en-us/library/system.string.isnullo...

Det exemplet går väl igenom precis det du ska göra, bara att du får ändra så att du använder en loop istället.

Visa signatur

|| Intel 8700K || Asus RTX 4070 TI Super TUF || Samsung 750 EVO 500GB & Kingston A2000 1TB & Samsung 960 EVO 250GB || Corsair RM 850x || Antec P183 || Asus G-Sync RoG Swift PG279Q || Dell XPS 15 || Thinkpad X220

The Force is like Duct Tape, it has a light side, a dark side, and holds the universe together.

Permalänk
Medlem

Jag har lyckats komma en bit på vägen, men nu har jag fastnat igen. Ska skriva en metod som skall returnera info om varje "seat" i en array. Jag gör ett bokningsystem.

"This is a method that formats and returns an output string for a seat at
the position number that is equal to index. The method can be called for
every seat using a loop inside the class or in the MainFrame. The latter
alternative is more object-oriented and is to prefer."

Ungefär den info jag har.. Förstår inte alls hur jag ska börja här, så vilken hjälp som helst hade varit väldigt uppskattat! Behöver inte vara hela lösningen, gärna inte, men en början..

Har kommit såhär lång typ.

public string GetSeatInfoAt(int index)

Permalänk

public string GetSeatInfoAt(int index) { return "Info" } for(int i = 0; i < array.length; i++) { String info = GetSeatInfo(i); }

Nått sånt eller?

Permalänk
Medlem
Skrivet av Shkipan:

Hej!

Jag vill loopa igenom en array, räkna ut och returnera antal platser som är reserverade. Jag vill alltså kolla elementen i arrayen för att se om de är null eller empty. Men jag fattar inte riktigt hur jag ska lyckas med det

for(int index = 0; index < nameList.Length; index++)
{
Här vill jag alltså kolla vilka som är null elr empty men fattar inte riktigt hur jag kan göra det på ett smidigt sätt.
Typ if index is null or empty...
}

Tacksam för lite hjälp på vägen!

Mitt tips är i så stor utsträckning som möjligt helt strunta i loopar när du behandlar listor eller arrayer av likartade element. Att räkna ut antalet element som motsvarar ett kriterium är så enkelt som

nameList.Where(name => string.IsNullOrEmpty(name)).Count();

Ovan anges VAD som ska räknas, inte HUR det ska göras.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Skrivet av Teknocide:

Mitt tips är i så stor utsträckning som möjligt helt strunta i loopar när du behandlar listor eller arrayer av likartade element. Att räkna ut antalet element som motsvarar ett kriterium är så enkelt som

nameList.Where(name => string.IsNullOrEmpty(name)).Count();

Ovan anges VAD som ska räknas, inte HUR det ska göras.

Jag vet inte om det kanske är lite överkurs att blanda in Linq-frågor när OP uppenbarligen är nybörjare. Loopar brukar vara det första som man lär sig och som faktiskt är väldigt nyttigt att kunna.

Permalänk
Medlem
Skrivet av DenSammeSamme:

Jag vet inte om det kanske är lite överkurs att blanda in Linq-frågor när OP uppenbarligen är nybörjare. Loopar brukar vara det första som man lär sig och som faktiskt är väldigt nyttigt att kunna.

LINQ är grundläggande inom .NET och minst lika viktigt att förstå som loopar. När frågan är så specifik som den var i detta fall är det extra relevant. Hade frågan handlat om hur loopar fungerar rent generellt hade det varit en annan sak.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Datavetare
Skrivet av Teknocide:

LINQ är grundläggande inom .NET och minst lika viktigt att förstå som loopar. När frågan är så specifik som den var i detta fall är det extra relevant. Hade frågan handlat om hur loopar fungerar rent generellt hade det varit en annan sak.

I en perfekt värld kanske detta varit sant, i den värld vi lever i så är det den bistra sanningen att LINQ faktiskt är förbjudet enligt flera företags kod-standard då många upplever resultatet som svårläst. LINQ även fått rykte som sig att resulterar i långsam kod p.g.a. att folk överanvänt LINQ till "smarta" lösningar som genererat enorma mängder kortlivade objekt, något som kan påverka hela systemet negativt.

Personligen tycker jag LINQ är en riktigt trevlig teknik, men har ändå förståelse för kritiken.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

I en perfekt värld kanske detta varit sant, i den värld vi lever i så är det den bistra sanningen att LINQ faktiskt är förbjudet enligt flera företags kod-standard då många upplever resultatet som svårläst. LINQ även fått rykte som sig att resulterar i långsam kod p.g.a. att folk överanvänt LINQ till "smarta" lösningar som genererat enorma mängder kortlivade objekt, något som kan påverka hela systemet negativt.

Personligen tycker jag LINQ är en riktigt trevlig teknik, men har ändå förståelse för kritiken.

Är inte världen ofta perfekt ur ett pedagogiskt perspektiv? Man utvecklar efter de senaste principerna med den senaste mjukvaran.

Jag har svårt att tro att det i Sverige i dag finns utbildningar som specifikt inriktar sig mot .NET 3.0. Att storföretagspolicy förbjuder LINQ är inte anledning att inte lära sig det. Samma företag/statliga institutioner sitter ofta kvar med Windows XP/IE7 men det är HTML5 och CSS3 som lärs ut i skolorna (som tur är).

LINQ är ett naturligt steg i utvecklingen, även om det är lite väl hajpat i .NET.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Skrivet av Teknocide:

LINQ är grundläggande inom .NET och minst lika viktigt att förstå som loopar. När frågan är så specifik som den var i detta fall är det extra relevant. Hade frågan handlat om hur loopar fungerar rent generellt hade det varit en annan sak.

jag får en känsla av att den uppgift som OP troligen fått handlar just om förstå loopar och hur man kan använda dem och precis som virtual void säger så är LINQ inte särskilt lättläst. i synnerhet inte om man saknar grundläggande kunskap i SQL eller liknande.

däremot har jag aldrig (i mitt iofs rätt korta arbetsliv) stött på något förbud mot LINQ.

Citat:

Är inte världen ofta perfekt ur ett pedagogiskt perspektiv? Man utvecklar efter de senaste principerna med den senaste mjukvaran.

det här är ju dock helt fel. det finns tråkigt många system byggda i gamla språk/versioner där det inte finns LINQ och därmed är det direkt nödvändigt att kunna grunderna. det funkar inte att komma ut till ett jobb senare i livet och inte kunna loopar bara för att senaste versionen av .net har LINQ

Permalänk
Medlem
Skrivet av DenSammeSamme:

jag får en känsla av att den uppgift som OP troligen fått handlar just om förstå loopar och hur man kan använda dem och precis som virtual void säger så är LINQ inte särskilt lättläst. i synnerhet inte om man saknar grundläggande kunskap i SQL eller liknande.

däremot har jag aldrig (i mitt iofs rätt korta arbetsliv) stött på något förbud mot LINQ.

det här är ju dock helt fel. det finns tråkigt många system byggda i gamla språk/versioner där det inte finns LINQ och därmed är det direkt nödvändigt att kunna grunderna. det funkar inte att komma ut till ett jobb senare i livet och inte kunna loopar bara för att senaste versionen av .net har LINQ

Jag tycker LINQ är grymt lättläst, mycket lättare än en loop. Sen har det väldigt lite med SQL att göra (MS har valt att presentera LINQ och i synnerhet LINQ-comprehensions på det viset, vilket kanske var ett misstag). I andra programmeringsspråk, speciellt funktionella, är LINQ-liknande arbetssätt standard. På senare tid blandar man i mer och mer funktionellt tänk i objektorienterad programmering just för att det är lättare att resonera kring.

Vad jag menar med "pedagogiskt perspektiv" är att utbildningar lär ut det senaste inom det fält de undervisar i. LINQ är ingen nyhet i sig men blir mer och mer relevant, inte minst det "nya tänket" som det representerar. Givetvis ska man inte ersätta kunskap om loopar med LINQ men det är minst lika relevant och inte krångligare på något sätt. Jämfört med LINQ är loopar väldigt lågnivå.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Skrivet av Teknocide:

Jag tycker LINQ är grymt lättläst, mycket lättare än en loop. Sen har det väldigt lite med SQL att göra (MS har valt att presentera LINQ och i synnerhet LINQ-comprehensions på det viset, vilket kanske var ett misstag). I andra programmeringsspråk, speciellt funktionella, är LINQ-liknande arbetssätt standard. På senare tid blandar man i mer och mer funktionellt tänk i objektorienterad programmering just för att det är lättare att resonera kring.

Vad jag menar med "pedagogiskt perspektiv" är att utbildningar lär ut det senaste inom det fält de undervisar i. LINQ är ingen nyhet i sig men blir mer och mer relevant, inte minst det "nya tänket" som det representerar. Givetvis ska man inte ersätta kunskap om loopar med LINQ men det är minst lika relevant och inte krångligare på något sätt. Jämfört med LINQ är loopar väldigt lågnivå.

LINQ kan vara lättläst om det är rätt formaterat :).

Jag har ingen erfarenhet av funktionella språk så jag litar på att du har rätt och utifrån min egna erfarenhet tyckte jag att det var enklare att förstå LINQ om jag använde samma tänk som när jag skrev SQL.

Sen håller jag inte med om att utbildningar ska lära ut det senaste inom det fältet. Det är, i min mening, inte en utbildnings syfte utan snarare att ge en grundläggande kunskap och en plattform för att kunna lära sig mer. Dessutom kände jag inte att jag lärde mig någon slags spjutspets-teknologi när jag gick på universitetet. Gjorde du det?

Permalänk

Sluta tjafsa. LINQ ingår inte i programmering 1-2 där for/do och while ingår så även om det var ett bra tips så var det lite utanför TS förmodade kunskapsområde.

Visa signatur

http://www.snaljapen.se/ Snåljåpens blogg om pengar, sparande och investeringar.

Permalänk

Om det är första kursen man programmerar så är det väldigt uppenbart att man måste lära sig hur for-loopar fungerar. Och inte hur Linq fungerar, speciellt med tanke på att det är enbart för .NET och for-loopar finns i ~alla språk, bara för att man använder C#.NET i skolan så betyder det knappast att man nödvändigtvis kommer jobba med det.

Permalänk
Medlem

Självklart ska man lära sig grunderna först.

Linq liknande språk kommer nog komma till de flesta språk i framtiden, nästa Java kommer få lambda uttryck och extension methods vilket öppnar upp för att integrerar linq liknande språk i framtiden.

Det är helt enkelt nödvändigt då huvuddelen av all programmering är att manipulera data från olika strukturer fram och tillbaka, att göra det med enbart loopar är inte produktivt.

Redan idag finns det olika portningar för det i de flesta språk men det är inte integrerat så djupt i runtime och kompilatorn som det är i C#/.NET

Så visst finns det anledning att lära sig linq, men inte innan man lärt sig grunderna ordentligt först.

Permalänk
Medlem
Skrivet av DenSammeSamme:

LINQ kan vara lättläst om det är rätt formaterat :).

Jag har ingen erfarenhet av funktionella språk så jag litar på att du har rätt och utifrån min egna erfarenhet tyckte jag att det var enklare att förstå LINQ om jag använde samma tänk som när jag skrev SQL.

Sen håller jag inte med om att utbildningar ska lära ut det senaste inom det fältet. Det är, i min mening, inte en utbildnings syfte utan snarare att ge en grundläggande kunskap och en plattform för att kunna lära sig mer. Dessutom kände jag inte att jag lärde mig någon slags spjutspets-teknologi när jag gick på universitetet. Gjorde du det?

Det beror helt på vilken typ av utbildning det handlar om. Går du en yrkesutbildning i webbutveckling med ASP.NET i dag kommer du garanterat få lära dig MVC 3/4 samt .NET 4.0/4.5, IIS, WCF eftersom det är det som används på marknaden. Webb är förvisso ett snabbt snurrande media med snabbt anammade nyheter.

I ett bredare program är troligtvis även programmeringskurserna bredare och mer grundläggande. Vanligtvis får man lära sig flera språk, jag vet dem som läst Java och Haskell, eller Prolog. Man får en bredare kännedom om programmeringsteori.

Jag har gått blandade kurser och fått lära mig mycket spetsgrejer inom Java (som nu är förlegade), men även mer abstrakta och teoretiska kurser som går att applicera i ett flertal programmeringsspråk. Du har ju helt rätt i att det inte nödvändigtvis måste handla om just LINQ, jag antog helt enkelt att det var en fokuserad kurs i C# som lästes.

Skrivet av snåljåpen:

Sluta tjafsa. LINQ ingår inte i programmering 1-2 där for/do och while ingår så även om det var ett bra tips så var det lite utanför TS förmodade kunskapsområde.

Skrivet av Balls Of Steel:

Om det är första kursen man programmerar så är det väldigt uppenbart att man måste lära sig hur for-loopar fungerar. Och inte hur Linq fungerar, speciellt med tanke på att det är enbart för .NET och for-loopar finns i ~alla språk, bara för att man använder C#.NET i skolan så betyder det knappast att man nödvändigtvis kommer jobba med det.

Skrivet av yxz:

Självklart ska man lära sig grunderna först.

Linq liknande språk kommer nog komma till de flesta språk i framtiden, nästa Java kommer få lambda uttryck och extension methods vilket öppnar upp för att integrerar linq liknande språk i framtiden.

Det är helt enkelt nödvändigt då huvuddelen av all programmering är att manipulera data från olika strukturer fram och tillbaka, att göra det med enbart loopar är inte produktivt.

Redan idag finns det olika portningar för det i de flesta språk men det är inte integrerat så djupt i runtime och kompilatorn som det är i C#/.NET

Så visst finns det anledning att lära sig linq, men inte innan man lärt sig grunderna ordentligt först.

Frågan som ställs är specifikt hur man räknar ut antalet element som fyller ett visst kriterium i en samling, och frågan handlar specifikt om C#. LINQ är det absolut bästa sättet att ta sig an uppgiften på. Hade frågan varit mer generell som "hur repeterar jag en sak sju gånger?" så hade det inte gått (eller inte varit logiskt/smidigt) att lösa den med LINQ.

Ni måste väl ändå kunna erkänna att den bästa lösningen är bäst?

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Datavetare
Skrivet av Teknocide:

LINQ är det absolut bästa sättet att ta sig an uppgiften på. Hade frågan varit mer generell som "hur repeterar jag en sak sju gånger?" så hade det inte gått (eller inte varit logiskt/smidigt) att lösa den med LINQ.

Ni måste väl ändå kunna erkänna att den bästa lösningen är bäst?

Beror helt på vad man menar med "bäst". För 6-8 år sedan trodde alla att funktionell programmering skulle lösa de flesta problem man insåg att man kom att få när det inte längre gick att öka klockfrekvensen på CPUer och man gick till multicore CPUer. Och i teorin är det en lösning.

Men i praktiken har det (i alla fall än så länge) visat sig att funktionella språk duger fortfarande bara till undervisning och enklare program där det i princip kvittar vad man använder. Problemet med funktionella språk och funktionell programmering i allmänhet är att det nästan alltid leder till att man skapar betydligt fler kortlivade objekt än vad är fallet med imperativ programmering. Det kopplat med moderna "concurrent GC" (stop-the-world GC kommer nog inte på fråga) så har man ett recept på något som är långsamt och skalar brutalt illa då det är väldigt "elakt" mot moderna CPU-cachar. I multicore-programmering så är "cache king" och hanterar man den inte på rätt sätt så är det bättre att låta programmet fortsätta vara enkeltrådat.

for(int index = 0; index < nameList.Length; index++) { if(nameList[i] == null) { ... } }

skapar noll kortlivade objekt och kan antagligen hålla allt i CPU-register -> väldigt snabbt

nameList.Where(name => string.IsNullOrEmpty(name)).Count();

skapar först en enumerable av nameList (minst ett kortlivat objekt + kod för att initiera)
string.IsNullOrEmpty(name) är dels ett lambdauttryck, som kan även det skapa ett temporärt objekt men inte säkert då det i detta fall inte är en closure. IsNullOrEmpty är däremot en metod på ett objekt, något som betyder minst 3 minnesaccesser (1. få tag i objektet, 2. få tag i klass instansen, 3. läsa ut adressen för IsNullOrEmty).

Och för att toppa det hela så utför man i detta läget ett hopp baserat på ett dynamiskt värde, en operation som är väldigt svårt att förutse för en modern CPU då hopp "tar effekt" väldigt sent i pipeline:en medan man måste i alla fall ha en gissning vart man hoppar tidigt i pipeline:en (i avkodaren) annars får man en pipeline-stall, framförallt på lite enklare CPUer typ de vi har i våra mobiler och pekplattor. Just detta har inget att göra med funktionell programmering, dynamisk dispatch är mer ett sätt att implementera polymorfism i de flesta fall.

Metoden Where är statisk, så där vet man hopp adressen statiskt, dock så producerar denna ett ny temporär objekt (enumerable) som man åter igen gör ett dynamiskt hopp till dess Count metod.

Så "bättre" är verkligen beroende på vad man vill åstadkomma, gamla vanliga C (inte C++) är fortfarande det absolut vanligaste språket för riktigt stora projekt. Inte för det har mest och coolast finesser, snarare tvärt om, det är relativt enkelt och det utföra absolut inget man inte explicit ser vilket är kritiskt i riktigt stora system som väldigt många personer jobbar på (alla med väldigt varierande kunskap och expertis).

Sedan kan jag inte låta bli att påpeka att LINQ må vara en riktigt cool finess, men det är definitivt inget Microsoft kommit på och det är inget C# är först med. De som utvecklade LINQ är helt öppna med att de ville stoppa in en del av kraften från Lisp i C# och tittar man på t.ex. Clojure (modern Lisp dialekt) så inser man att LINQ bara en en liten del av vad man helt naturligt kan göra med Lisp. Exemplet ovan skulle i Clojure bli

(count (filter empty? nameList))

eller lite mer likt kanske

(->> nameList (filter empty?) (count))

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Beror helt på vad man menar med "bäst".

Det var medvetet lite flame-bait i det uttalandet. Jag menar "bäst för det ändamål som angetts", vilket bara är aningen mindre luddigt men ur ett rent kodperspektiv anser jag det vara obestridbart. Det finns inga indikationer på att koden är tidskritisk på något vis, och ska den bara köras en gång i sekunden eller mindre så är skillnaderna så marginella att de inte märks.

Citat:

nameList.Where(name => string.IsNullOrEmpty(name)).Count();

Angående kodexemplet, det finns overhead men det går inte att jämföra statiskt kompilerad C-kod med ett språk som optimeras under runtime. JITtern arbetar med bytekoden under runtime vilket jag är säker på att du känner till och skillnaden mellan iterationer är påtaglig. Antalet kortlivade objekt som skapas är också få och bör inte ha märkbar effekt på prestandan.
(kodsnutten kan förresten göras ännu mer elegant genom att direkt anropa string.IsNullOrEmpty som en delegate:

nameList.Where(string.IsNullOrEmpty).Count();

Det ser näst intill ut som ren engelska skriven av någon som tagit fel på punkt- och mellanslagstangenten..)

LINQ-satsen fungerar på alla IEnumerables och inte bara Array-liknande datastrukturer. Den är kortare och enklare att både läsa och skriva vilket innebär mindre chans för en bug (du skrev t ex i istället för index).

Implementationen av .Where och .Count är inte given: Om den i dag innebär overhead skulle den imorgon lika gärna kunna resultera i bytecode motsvarande low level-loopen du visade (bortsett från string.IsNullOrEmpty, som dock kommer inlinas). Ju högre abstraktionsnivån blir desto större möjligheter finns det för den underliggande arktitekturen att göra osynliga men påtagliga optimeringar. for-loopen å andra sidan kommer förbi en for-loop; en lågnivåkonstruktion som dikterar sin egen funktion.

C# är ett brett språk på så vis att det möjliggör insteg i både lågnivå och högnivå, men det säljs och används i störst utsträckning som ett högnivåspråk så varför inte använda det som ett sådant? LINQ är en av de mest intressanta egenskaperna .NET-plattformen har (reified generics som folk verkar tokiga i tycker jag är ganska ointressant..) och det är grundläggande sedan version 3.5. Hela jäkla collections-delen av standardbiblioteket använder sig av det och många andra delar också.

Citat:

Sedan kan jag inte låta bli att påpeka att LINQ må vara en riktigt cool finess, men det är definitivt inget Microsoft kommit på och det är inget C# är först med. De som utvecklade LINQ är helt öppna med att de ville stoppa in en del av kraften från Lisp i C# och tittar man på t.ex. Clojure (modern Lisp dialekt) så inser man att LINQ bara en en liten del av vad man helt naturligt kan göra med Lisp.

Jepp. Jag är inte särskilt förtjust i .NET men gillar vissa sidor hos det. LINQ har utöver det funktionella arvet lite extraeffekter som Expression Trees, men det är väldigt statiskt knutet i .NET-arkitekturen. C# är ett språk som växer åt alla håll och kanter och det börjar bli lite väl många kitchen sinks. Med det sagt gillar jag som du säkert förstått den funktionella approachen som görs tillgänglig – och jag är helt övertygad om att vi kommer få se mer av det längre fram även i andra språk, objektorienterade eller ej.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Datavetare
Skrivet av Teknocide:

Angående kodexemplet, det finns overhead men det går inte att jämföra statiskt kompilerad C-kod med ett språk som optimeras under runtime. JITtern arbetar med bytekoden under runtime vilket jag är säker på att du känner till och skillnaden mellan iterationer är påtaglig. Antalet kortlivade objekt som skapas är också få och bör inte ha märkbar effekt på prestandan.

Det du skriver om dynamisk re-JIT är sant för Java (JVM) men inte sant för C# (CLR). CLR har bara en one-time JIT och kan därför inte utföra vissa typer av optimeringar som senare kan behöva tas bort. CLR saknar (i alla fall i version 5.0) även s.k. escape-analysis, något som i vissa fall gör det möjligt att lägga kortlivade objekt på stacken i de fall runtime:en kunnat garantera att de aldrig kan "fly" från aktuellt kontext. Detta syns numera rätt väl om man jämför motsvarande program skrivet i Java och C#, Java7 (efter JIT-warmup) tenderar att vara 30-40% snabbare än motsvarande C#4.5 program.

Så i C#/LINQ får du exakt alla de kostnader jag beskrev, hade Java haft LINQ så hade vissa varit möjliga att undvika. Nackdelen med Javas mer aggressiva JIT:ande är att det typiskt går åt mer CPU-cykler initialt + att mängden RAM som går åt är mycket högre. Verkar som MS aktivt valt att inte implementera detta i .Net då man vill att detta ska kunna användas både i relativt kortlivade och interaktiva program (desktop-program) samt även på servers. Java verkar bara rikta in sig på serversidan idag.

Och trots alla dessa optimeringar har jag fortfarande aldrig sett ett icke-trivialt (d.v.s något mer avancerat en än microbenchmark) som visar att Java är snabbare än motsvarande program skrivet i C eller C++. Jag hävdar däremot inte att Java är långsamt, tvärtom är dagens JVM:er riktigt riktigt bra!

Skrivet av Teknocide:

(kodsnutten kan förresten göras ännu mer elegant genom att direkt anropa string.IsNullOrEmpty som en delegate:

nameList.Where(string.IsNullOrEmpty).Count();

Det ser näst intill ut som ren engelska skriven av någon som tagit fel på punkt- och mellanslagstangenten..)

Och med den omskrivning blir det också explicit att man använder dynamisk dispatch som CLR inte kan optimera bort, men >=Java6 (möjligen Java5) skulle eventuellt kunna skriva en sådant anrop till att använda statisk dispatch.

Skrivet av Teknocide:

LINQ-satsen fungerar på alla IEnumerables och inte bara Array-liknande datastrukturer. Den är kortare och enklare att både läsa och skriva vilket innebär mindre chans för en bug (du skrev t ex i istället för index).

Jag skrev ingen koden förutom Clojure exemplet, allt var cut-and-paste. Och då det är ett statiskt typat och komplierat språk hade man ändå hittat det direkt + att den typen av felskrivningar var definitivt inget jag märkte att helt försvann när man programmerar språk som Haskell, Scala eller Clojure varav det kan bli ganska svåra fel att hitta i Clojure som är dynamiskt typat.

Skrivet av Teknocide:

Implementationen av .Where och .Count är inte given: Om den i dag innebär overhead skulle den imorgon lika gärna kunna resultera i bytecode motsvarande low level-loopen du visade (bortsett från string.IsNullOrEmpty, som dock kommer inlinas). Ju högre abstraktionsnivån blir desto större möjligheter finns det för den underliggande arktitekturen att göra osynliga men påtagliga optimeringar. for-loopen å andra sidan kommer förbi en for-loop; en lågnivåkonstruktion som dikterar sin egen funktion.

I C#/CLR: nej. Kompilera detta och titta i bytekoden (se nedan, jag stoppade in uttrycket i en statisk metod som jag kallade "bar"), funktionen nedan är en automatiskt skapad anonym funktion (d.v.s "name => string.IsNullOrEmpty(name)") anropet till string.IsNullOrEmpty är inte inline, däremot ser man att det är en metod som är statiskt definierad i klassen string.

.method private static hidebysig default bool '<bar>m__0' (string name) cil managed { .custom instance void class [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::'.ctor'() = (01 00 00 00 ) // .... // Method begins at RVA 0x2168 // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call bool string::IsNullOrEmpty(string) IL_0006: ret }

I Java: kanske, men det är lång rad krav som måste vara uppfylld innan re-JIT kan utföra de lite mer aggressiva optimeringarna.

Skrivet av Teknocide:

C# är ett brett språk på så vis att det möjliggör insteg i både lågnivå och högnivå, men det säljs och används i störst utsträckning som ett högnivåspråk så varför inte använda det som ett sådant? LINQ är en av de mest intressanta egenskaperna .NET-plattformen har (reified generics som folk verkar tokiga i tycker jag är ganska ointressant..) och det är grundläggande sedan version 3.5. Hela jäkla collections-delen av standardbiblioteket använder sig av det och många andra delar också.

Varför man inte kan (eller i alla fall inte bör) använda alla funktioner och finesser i ett så stor språk som C# och en så stor plattform som .Net inser man så fort det används i riktigt stora projekt, det fungerar inte att använda mer en relativt enkel delmängd. Felet med C#/.Net är kanske att det är för stort och komplicerat idag, Java (språket) börjat tyvärr också lockas av att plocka in för mycket. Stora projekt betyder många människor, många människor betyder många stilar och framförallt väldigt varierande kunskapsnivå. Ett sätt att hålla saker under någorlunda kontroll är att hindra ALLA från att använda de mest kraftfulla (och därmed "farliga") verktygen.

Titta på företag som Microsoft, Google och Facebook eller rättare sagt titta på deras kod-standard: de är alla företag som kör C++ på de mest kritiska komponenterna, men det är en extremt simplifierad variant av C++. Microsoft säger ju själva att de kör med C-with-classes. Googles kodstandard kan du hitta med t.ex. Google. Jobbar själv på ett företag som har kodbaser på många miljoner rader som används i prestandakritiska system, vi har precis börja tillåta C99 (körde C89 fram till två år sedan). Vi har inget förbud mot att använda "avancerade" saker som funktionspekare eller rekursion, men om du använder dessa så kommer du behöva förklara varför det är en bra idé. Framförallt rekursion kräver att man kan visa att djupet har ett väldefinierat max och att detta max är OK givet den stack man har på systemet.

Edit: det slog mig att jag faktisk bara visade att den genererade CIL inte inline:ar något. Men tar man upp den JIT:ade assemblern så ligger det faktiskt 2 call opkoder i den funktionen, den ena är till adressen för string::IsNullOrEmpty, men den andra (som sker två rader innan) är jag inte helt 100 på varför den behövs, den verkar hämta argumentet på något sätt (översättningen av ldarg.0 ?). Vilket i så fall betyder att en så pass enkel funktion genererar två call i maskinkod.

Ber om ursäkt för att detta gick lite väl OT :/

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem

Wow, finns det programmerare som fortfarande håller på med C++ vs. java vs. .NET diskussioner ?

Själv använder jag allihopa utan något behov att diskutera vad som är "bäst för stora projekt".

De som håller på med AI sysslar mest med Matlab nuförtiden just på grund av extrema högnivå abstraktioner som finns där, att gå till det som är mest low level hela tiden ger inte de uttrycks-möjligheter som finns med högre nivå språk, i så fall skulle vi alla syssla med assemblerkodning fortfarande.

Right tool for the right job.

Permalänk
Datavetare
Skrivet av yxz:

Right tool for the right job.

Helt sant!

Men alla som hävdar att .Net fungerar för stora projekt har aldrig jobba på ett sådant, för det är helt enkelt inte rätt verktyg. Inte ens Microsoft använder .Net för sådant. .Net är ett väldigt bra ersättare för VB5/6 för att göra LOB (Line Of Business), något som omsätter massor med pengar och det är väldigt många som jobbar med detta, så jag försöker inte nedvärdera .Net på något sätt!

Kan ju ha fel, men peka i så fall på ett enda projekt eller produkt som innefattar >100 personer och ett par miljoner rader kod som använder något annat än C, C++ eller möjligen Java och då med en custom-implementerad JVM som t.ex. Azul-systems "Zing".

Den enda nya kandidaten jag kan se är Go (golang.com) som specifikt utvecklats som en modern ersättare till C och specifikt designats för att kunna användas i Googles backend system (som består av massor med kod och har massor med utvecklare). Designkriterierna i Go var: skapa ett språk med minimalt antal finesser då det inte kommer kunna användas i stora projekt annars.

Och diskussionen har aldrig varit om A vs. B, det var kring huruvida man ska eller inte ska använda alla tillgängliga finesser.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Avstängd
Skrivet av Yoshman:

Helt sant!

Men alla som hävdar att .Net fungerar för stora projekt har aldrig jobba på ett sådant, för det är helt enkelt inte rätt verktyg.

Lol, har du noll koll?
Vad menar du med stora btw? Enterprise eller Webscale? .NET fungerar för båda hur som helst. Allt handlar om att skala.
Jag jobbar som Systemarkitekt och när jag tar fram arkitekturen för ett system ser jag till att de går att skala parallellt eller att de är enkla att skrivas om för att skala parallellt. Tex är ju CQRS jävligt hett just nu PGA dess förmåga att skala parallellt, de största grabbarna inom CQRS är just .NET gubbar

Parallell skalning har absolut ingenting med programspråket att göra, dock tycker jag managed code ala .NET eller Java är att föredra i stora projekt då det oftast är enklare att underhålla samt hitta folk so är duktiga inom.

edit: Vad man gör är att ha en central servicebuss (Denna kan vara in process i början) som skickar data och de som är intresserade av medelenandet agerar på det. Sedan när behov av skalning krävs flyttar man bussen från processen till en MQ lösning

Visa signatur
Permalänk
Datavetare
Skrivet av CyberVillain:

Lol, har du noll koll?
Vad menar du med stora btw? Enterprise eller Webscale? .NET fungerar för båda hur som helst. Allt handlar om att skala.
Jag jobbar som Systemarkitekt och när jag tar fram arkitekturen för ett system ser jag till att de går att skala parallellt eller att de är enkla att skrivas om för att skala parallellt. Tex är ju CQRS jävligt hett just nu PGA dess förmåga att skala parallellt, de största grabbarna inom CQRS är just .NET gubbar

Parallell skalning har absolut ingenting med programspråket att göra, dock tycker jag managed code ala .NET eller Java är att föredra i stora projekt då det oftast är enklare att underhålla samt hitta folk so är duktiga inom.

edit: Vad man gör är att ha en central servicebuss (Denna kan vara in process i början) som skickar data och de som är intresserade av medelenandet agerar på det. Sedan när behov av skalning krävs flyttar man bussen från processen till en MQ lösning

Ah, en arkitekt och även expert på .Net. Kan du då förklara för mig hur jag ska designa mitt program, på en väldigt hög nivå, för att kunna hantera upp emot 100k HTTP-transaktioner per sekund och CPU sockel. Systemet jag designat klara över 150k transaktioner per sekund och CPU-sockel (CPU i detta fall är 8-kärnors Xeon). Sessionerna är väldigt kortlivade, men du måste ändå designa programvaran att hantera tiotusentals samtida sessioner.

Detta är ungefär kraven du har om du ska skapa programvara för datacenter. Alla mobila enheter har drivit upp antal transaktioner per sekund samtidigt som mängden data som skickas per session minskat, något som inte precis gör det enklare att designa programvaran som ska levera innehåll till dessa enheter...

Är övertygad att du inte ens når en tiondel med .Net, du kommer definitivt inte kunna hålla tiotuseltals samtida session "in-flight", inte per CPU-sockel i alla fall. Även om det är relativt enkelt att skala genom att addera fler servers så betyder det också att kostnad för el och maskiner drar iväg så det blir helt enkelt inte kostnadseffektivt när det finns konkurrenter som löst problemet på sätt som kräver långt mindre resurser, även om de tar väldigt mycket pengar för sina lösningar.

Vi använder C, men har faktiskt testat att göra proof-of-concept på vissa delar i Go och var imponerad över hur pass enkelt det var att designa högpresterande nätverksprogramvara i detta språk. Kanske inte helt oväntat med tanke på det är exakt vad Google själva behöver och de designade ju Go just för sådana laster. Når inte riktigt 100k transaktioner per sekund, men faktiskt inte så lång ifrån och det är MYCKET mindre och enklare kod i Go jämfört med C. "Tricket" är att man i Go (precis om i Erlang) kan skriva kod som använder sig av blockande send/receive och sedan köra en sådan instans per session i något kallat Go-routine (process i Erlang). Att använda trådar i Java/.Net skulle totalt sänka OS:et då det tar alldels för mycket resurser att ha tiotusentals trådar, async/await fungerar inte heller då det inte är designat för den typen av arbetslast.

Och du har rätt, det handlar inte om språket, det handlar om runtime-plattformen. Och var precis det jag nämnde i fallet Java, finns specialdesignade JVM-implementationer med betydligt bättre skalbarhet än standardvarianterna från Oracle och IBM. Men har aldrig hört någon som använder .Net som runtime-plattform för system som ska hantera riktigt stora laster (datacenter nivå), men det kanske finns och skulle vara kul att veta vart i så fall.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Avstängd

Jag byggde ett Högfrekvenshandelsystem till en kund för ett tag sedan så kallad bothandel. Kravet var 2 000 000 transaktioner i sekunden. Vi klarade det i benchmark med några extra 100k i .NET. Googla Starcounter....

Visa signatur