webForumDet fria alternativet

Prestandatänk vid nyutveckling

.NET

31 svar · 808 visningar · startad av Brimba

Medlem sedan dec. 19995 874 inlägg
Frågan#1

Hej!

Hur ser ni på att bygga objektorienterat eller inte bygga objektorienterat vid större projekt som kräver enorm prestanda?

Har ni erfarenhet? Berätta gärna om hur det var i ert fall.

Är det någon som har byggt ett system objektorienterat med sedan fått bygga om på grund av prestandaproblem?

Medlem sedan juli 20011 304 inlägg
#2

Jag ser det inte som ett alternativ i huvudtaget att bygga någonting ej objektorienterat i .NET eller Java. Det går nästan inte. Jag anser att man kan bygga något med väldigt dålig objektmodell och något med en väldigt bra objektmodell (och allt däremmelan) men sjäva frameworket tycker jag inte att det går att jobba med proceduriellt. (visst nån enstaka funktion men inte som helhet)

Det som man kan undvika är att utföra tidsödande operationer (t.ex reflection). Enligt min erfarenhet sitter begränsningarna gissningsvis till 80% i kommunikationen med databasen.
Men det är klart: man ska aldrig säga aldrig.

Vad är enorm prestanda? Det känna som att om man vill åstadkomma enorm prestanda så håller man sig borta från webbapplikationer och CLR:er och JVM:er i största allmänhet! :)

Medlem sedan dec. 19995 874 inlägg
#3

Men samtidigt är det mycket snabbare att returnera en datareader och binda den i visningläget direkt istället för att ha egna klasser (data, collection, bl) för varje del som man binder mot.

Enorma system var kanske dåligt beskrivet men jag tänker på system som har över 10 miljoner förfrågningar till webbservern om dagen.

Medlem sedan apr. 20012 266 inlägg
#4

Som Jon använder även jag OOP uteslutande, vilket oftast bara medför fördelar. Har man t.ex en stor mängd förfrågningar mot en viss funktion/viss data kan man utan problem cacha denna, även data som behöver vara uppdaterad går bra att cacha (5s eller dyl).

Medlem sedan juli 20011 304 inlägg
#5

Det har du helt rätt i. Men jag ser inte det som om det inte vore objektorienterat. Du kan ju ha en funktion i ditt BLL som returnerar den datareader du vill binda.

Nyckeln till prestanda ligger ofta i cachning, vilket är enkelt att åstadkomma så länge man inte har data som presenteras som ändras hela tiden. Att tänka på då är att en datareader inte går att cache:a utan datat måste då fyllas i ett externt objekt (eller så användaer man t.ex en datatable)

Slutsats: Om sidan laddas många gånger med information som inte ändras alltför ofta blir det snabbare med ett custom object som cache:as. Om man ska dra ut data hela tiden är det snabbare med en datareader.

OT. Hur fasiken skall man stava cache och dess olika böjningar på svenska? :)

// red såg att det hade tillkommit en liknande post men låter denna vara kvar ändå...

Medlem sedan dec. 19995 874 inlägg
#6

Problemet är att om den som ställer frågan till funktionen skickar med massa användarspecifika parametrar. Då blir en cachefunktion relativt oanvändbar eftersom ingen användare har samma parametrar och ingen användare ställer samma fråga igen (inom rimligt tidsspann)

Medlem sedan dec. 19995 874 inlägg
#7

Jag skulle inte vilja klassa att binda en datareader till en repeater som att vara objektorienterat. Men det rör inte ämnet.

För att ge lite perspektiv på det hela så kan ni tänka er att ni bygger en sida och den sidan kommer att anropas 1 500 000 gånger per dag. Bygger ni den helt objektorietnerat med exempelvis 5 eller 7 lager så blir detta naturligtvis långsammare än om ni bara har ett datalager med en funktion som returnerar en datareader som ni sedan kopplar till er repeater i presentationen.
Tänk er sedan att ni har 20 sidor och varje sida anropas lika ofta. Det är scenariot och det är det vi får ha som utgångspunkt för diskussionen.
Samt då att ni i stort sett inte kan cacha någonting eftersom varje sida anropas med användarspecifika parametrar och resultatet till alla användarna skiljer sig alltså.

Har ni erfarenhet av detta eller gissar ni?

Medlem sedan juli 20011 304 inlägg
#8

Jag skulle inte vilja klassa att binda en datareader till en repeater som att vara objektorienterat

Varför inte? Skulle det vara mer objektorienterat att binda ett dataset eller en custom collection?

Det finns ingenting som säger att du inte kan programmera proceduriellt och använda 27 lager eller programmera objektorientera och använda 2 lager. Har ingenting alls med saken att göra faktiskt :)

Jag tror att det du är ute efter är att dela upp din applikation i en lämplig lagerstruktur. Objektorienteringen är mer vilka klasser/objekt som ansvarar för att utföra olika funktionalitet i applikationen.

Det kommer att bli en objektmodell även om du utför all funktionalitet i bara en aspx-sida - den blir bara mycket sämre ;)

Med det i åtanke och återgå till orginalfrågan så tror jag inte att du kommer märka skillnad i prestanda beroende på hur du strukturerar upp ansvaret och logiken på vilka objekt som anvarar fö vilken funktionalitet utan genom att tänka igenom lagerstrukturen och val av dataaccess.

I ditt fall kanske det slutar med:

1. UI - aspx-sidor
2. UI-logik - codebehind som formaterar, validerar och ropar på ett BLL eller rätt av på ett DAL
(3. eventuellt ett BLL om sådan tinns)
4. Ett DAL som ropar på Stored procedures och får tillbaka en datareader som binds.

Ditt DAL kommer att bestå av ett gäng klasser som ansvarar för att hämta data från rätt databas och hålla koll på kopplinar till denna. Eventuellt ansvarar det även för att välja rätt SP men det hör snarare hemma i ett BLL.

Visst kan du skapa dina koppling till databasen och ropa på dina SP direkt från codebehind men där ligger prestandavinsten på så små siffror att de är försummbara. Som sagt - det är databasaccessen som tar tid.

Men nu när jag tänker mig in lite i situationen förstår jag vad du menar med med att det inte skulle vara objektorienterat och kan hålla med om att det, eftersom du kommer att få ett objekt per sida som har allt ansvar. Jaja. Du förstår nog vad jag menar vid det här laget :)

Medlem sedan apr. 2004778 inlägg
#9

Samt då att ni i stort sett inte kan cacha någonting eftersom varje sida anropas med användarspecifika parametrar och resultatet till alla användarna skiljer sig alltså.

Stämmer inte. Det du cachar är resultatset som du med dina användarspecifika parametrar hämtar ditt resultat ur.
T.ex. en webbshop. Du cachar produktsortimentet. När en användare kommer in och ska se en specifik kategori så hämtas sortimentet i cachen och produkterna plockas ut därifrån.
I en objekt-orienterad arkitektur är då produktsortimentet en Collection av starkt typade objekt. Om kollektionen är oanvänd en längre tid så kommer den att försvinna ur cachen och första gången efter det kommer den att skapas igen och cachas. Om man gör en ändring i sortimentet så "slänger" man det som är i cachen och första gången efter det så skapas den igen.
En sajt som har mycket trafik där kollektionen används hela tiden vinner väldigt mycket på detta eftersom det inte behövs några databasanrop och man behöver inte skapa kollektionerna på nytt om och om igen.

Jag bygger alla mina lösningar i OOP. Det gör det lättare att bygga moduler som jag kan använda i framtida lösningar och som i sin tur är väldigt lätta att bygga ut genom t.ex. arv.

Medlem sedan dec. 19995 874 inlägg
#10

Varför inte? Skulle det vara mer objektorienterat att binda ett dataset eller en custom collection?

Nej, missuppfattning :)

Men nu när jag tänker mig in lite i situationen förstår jag vad du menar med med att det inte skulle vara objektorienterat och kan hålla med om att det, eftersom du kommer att få ett objekt per sida som har allt ansvar. Jaja. Du förstår nog vad jag menar vid det här laget

Jo vi förstår nog varandra även om jag kanske förklarade lite klumpigt :r

I denna diskussionen räknar vi inte in tiden för databasförfrågningen. Det är ett annat kapitel.

Det jag försöker reda ut är prestandaförluster när man konverterar sitt dt/dr/whatever till ett eget objekt som i och för sig har många fördelar men nackdelen är ju mellansteget att få in all data i sitt objekt. Istället för att skriva ut det direkt. Det är detta jag försöker diskutera :)
Samt att cachening inte går att använda annars hade det naturligtvis varit ett strålande tillfälle.

Medlem sedan apr. 2004778 inlägg
#11

Om det absolut inte går att cacha (stavning?) något så förlorar nog objekten på prestanda.
Men nyfiken som jag är, varför går det inte att cacha?

Medlem sedan juli 20011 304 inlägg
#12

Nu blev ju det hela solklart! :)

Jag håller med PDahlen och tror faktiskt att det går att cahce:a ändå om du inte har otroliga mängder data i databasen (envist va?)

Vet inte vad prestanda skillnaden du efterfrågar är. Du får väl göra ett test med/utan och köra det 1.000.000 gånger och räkna lite :) Men nån borde ha gjort tester och publicerat på nätet. Hojtar till om jag ser nån!

Medlem sedan dec. 19995 874 inlägg
#13

En sajt som har mycket trafik där kollektionen används hela tiden vinner väldigt mycket på detta eftersom det inte behövs några databasanrop och man behöver inte skapa kollektionerna på nytt om och om igen.

Problemet med detta är om det resultatet man har i cachen ändras ofta. Precis som du skriver så slänger man bara cachen och uppdaterar den med rätt. Men låt oss säga att den uppdateras varje gång en förfrågan gör. Vad vinner man på att cacha då? Jag ser det som en ren förlust eftersom man först måste göra en kontroll sedan slänga cachen sedan uppdatera cachen (läsa från databasen) och sedan läsa från cachen. Istället för att direkt läsa från databasen.

Men naturligtvis har du rätt i att om man har en produktlista så kan det vara ett bra sätt. Men tänk dig istället onlinelistan här på webForum. Varje gång någon kommer online så måste den slängas och sedan uppdateras.

r/ Onlinelistan är superduperviktigt att den är aktuell. Annars skulle man kunna cacha onlinedatan och inte uppdatera den på exempelvis 20 minuter, men i detta fallet är det viktigt att man får reda på vem som är online.

Medlem sedan apr. 2004778 inlägg
#14

Om jag inte är helt ute och cyklar (ni får väl skrika till) så skulle jag göra en sådan här lösning på onlinelistan.

1. Ett objekt per användare
2. En kollektion med användarobjekt skapas och cachas
3. När en person loggar in så skapas ett användarobjekt och läggs till i den cachade kollektionen
4. När någon loggar ut tas det objektet bort ur kollektionen.

Tankesättet kan översättas till annat.
Det viktiga är att objekt som ändras sällan finns i cachen.

MEN, sen finns det ett annat sätt att tänka om du läste mitt tidigare inlägg.
Det som cachas är ALLA användare. Eller om det är mycket så cachas de beroende på tidigare login så man bara cachar de som används ofta.
I global.asax har man en Application variabel som är en användarkollektion för inloggade.
När någon loggar in kollar man i användarcachen och lägger in korrekt användarobjekt i Application-kollektionen.

Vad tror ni om det?

Medlem sedan juni 20019 024 inlägg
#15

Jag tycker det hela är mycket enkelt.

Har man en miljon förfrågningar varje dag så har man en stor webbplats. Har man en stor webbplats har man pengar. Har man pengar köper man in jättestora servrar. Har man jättestora servrar klarar dessa miljoner och åter miljoner förfrågningar. ;)

Att programmera "linjärt" för att få upp prestandan finns absolut ingen anledning att göra. I stället blir det svårare att uppdatera och underhålla. Då måste man i stället lägga ned mer tid på programmering. Eftersom tid = pengar så kan man lika väl köpa in en bra server i stället för att lägga det på tid för arbete.

Medlem sedan mars 20007 896 inlägg
#16

Självklart ska du programmera objektorienterat. :)

F.ö. tycker jag att PDahlen säger något som är tänkvärt, objekt som inte uppdateras ofta ( Utan slängs och läggs till i cachen, som hans exempel med onlinelistan ) fungerar utmärkt att cacha. Så länge det inte gäller data som ska uppdateras är cachning mycket effektivt.

Medlem sedan dec. 19995 874 inlägg
#17

En kollektion av 100 000 användarobjekt sparat i cachen låter väl inte jätteroligt tycker jag...
Det andra alternativet att spara endast de som är online är väl mer rimligt i just detta fallet. Så det kanske var dåligt exempel av mig men det blir nog ändå problem om onlineantalet går uppemot 10000.

Samtidigt kan man inte spara allt i cachen heller. exempelvis om en användare skall söka alla användare som har parameter x och parameter y och är online. Då har man ju användarna som är online i cachen (om man nu har löst det så). Problemet är dock att det fortfarande är 10000 objekt, vilket blir en enorm mängd med minne eftersom varje anvädnare har en hel drös med parametrar kopplad till sig. Så det går nästan inte att göra så kan jag säga. Eller vad tror ni om 10000 användarobjekt i cachen.

Sedan får vi även betänka att en sida kan ligga på flera webbservrar. Var skall cachen lagras? XML på en cacheserver?
Om man lagrar applikationsvariabeln i en databaserver vad vinner man egentligen då på att cacha?

Medlem sedan dec. 19995 874 inlägg
#18

Har man en miljon förfrågningar varje dag så har man en stor webbplats. Har man en stor webbplats har man pengar. Har man pengar köper man in jättestora servrar. Har man jättestora servrar klarar dessa miljoner och åter miljoner förfrågningar.

En stor webbplats och mycket pengar är inte direkt alltid ett samband.
Vad menar du med mycket pengar? Har du kikat på vad det kostar med en klustrad sql-server lösning?
En webbserver är i sig inte speciellt dyr, problemen kommer när dessa skall kopplas ihop på ett bra sätt. Då blir det dyrt.

Medlem sedan dec. 19995 874 inlägg
#19

Självklart ska du programmera objektorienterat.

Bra argument! Jag köper det! ;)

Medlem sedan juli 20011 304 inlägg
#20

Sedan får vi även betänka att en sida kan ligga på flera webbservrar. Var skall cachen lagras?

På applikationsservern :)

374 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
121 ms — deklarationer (db)
118 ms — hämta statistik (db)
132 ms — hämta tråd, inlägg och bilagor (db)
116 ms — ändringar (db)