Snabbt kolla ifall filer på UNC finns C#

Permalänk

Snabbt kolla ifall filer på UNC finns C#

Hej!

I en applikation jag skriver kollar jag ett par hundra gånger mot olika filer ifall de finns. Om jag har filerna lokalt går det på nån hundradel men om det är på en UNC-share kan det ta upp emot en minut!

Använder mig av Directory.Exists(""), File.Exists("") samt deras motsvarigheter för fileinfo och directoryinfo. Någon som har en aning på ett snabbare sätt? Hittade ett sätt som tog cirka 20 ms för alla mot 30000 ms för alla med de ovan nämna alternativen. Problemet med den är att den använder sig av p/invoke och jag vill hålla mig till .net så att jag ska kunna använad mig av Mono i framtiden...

Någon som vet ett bra sätt att snabba upp detta på?

Tacksam!:)

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem

Börjar med kärnfrågan, varför kollar du ett par hundra gånger om olika filer finns? Varför inte använda dig av FileWatchers?

Permalänk
Citat:

Ursprungligen inskrivet av thrawn
Börjar med kärnfrågan, varför kollar du ett par hundra gånger om olika filer finns? Varför inte använda dig av FileWatchers?

Förstår att det låter lite konstigt, ska skriva lite mer utförligt. Jag har ju mitt program (länk i sign) som jag har en hel del xml-filer om filmer. I dem har jag en plats på filen skriven som jag läser in. När jag läser in varje fil validerar jag att den verkligen ska lägga till. Det finns en del saker som gör att den inte ska det. T.ex. att den inte finns, att den är exkluderad etc. Så därmed när jag läser in den kollar jag ifall den finns eller inte, gör den inte det har jag en funktion som kollar ifall man möjligen har bytt enhet på disken som filmerna ligger på (detta händer ifall man har allt på en extern disk).

Min tanke på att skriva om det skulle vara så att man istället loopade igenom alla filer som fanns och sen ta bort de som inte loopades igenom men känns som det skulle bli krångligare och även ta längre tid...

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem

ok, har kollat lite mer på hur ditt program jobbar nu och ska jag vara ärlig så verkar du angripa problemet från fel håll. Iaf enligt mig

1. Att använda en xml-fil istället för många, sen kan du läsa in hela i minnet istället för att läsa dom en och en. Om du inte vill att programmet ska ta upp för mycket minne kan du ju sätta en gräns på säg 100 filmer/xml fil och sen ha en annan xml-fil där du har referenser till i vilken xml-fil som filmens information är lagrad. Den senare metoden är jag lite osäker på hur prestandan blir, men den bör vara bra. Ett bättre alternativ är att använda sig av en "riktig" databas, t.ex. sqlite. Jag har byggt applikationer som har iaf några hundra tusen rader (inte mkt, men du kommer knappast komma över det i ett sånt här program) som presterar bättre än vad din nuvarande arkitektur gör med så förhållandevis få rader. Men det var kanske inte ditt största problem just nu
2. Läs in filstrukturerna i minnet och jobba mot det istället för att läsa mot hårddisken för varje. Du behöver ju inte loopa dig igenom alla filer heller utan du kan ju få en array med filerna direkt från .net, mycket smidigt. Sen kan du använda dig av linq för att ställa enkla frågor mot listorna. Du behöver inte ta bort filerna som du läst in från listan, det är ganska så tidsödande. Det här är naturligtvis inte det mest omptimala, men det bör vara ganska lite jobb för dig att skriva om och du kommer märka en sjuk skillnad jämfört om du kollar mot hårddisken hela tiden.

Permalänk
Citat:

Ursprungligen inskrivet av thrawn
ok, har kollat lite mer på hur ditt program jobbar nu och ska jag vara ärlig så verkar du angripa problemet från fel håll. Iaf enligt mig

1. Att använda en xml-fil istället för många, sen kan du läsa in hela i minnet istället för att läsa dom en och en. Om du inte vill att programmet ska ta upp för mycket minne kan du ju sätta en gräns på säg 100 filmer/xml fil och sen ha en annan xml-fil där du har referenser till i vilken xml-fil som filmens information är lagrad. Den senare metoden är jag lite osäker på hur prestandan blir, men den bör vara bra. Ett bättre alternativ är att använda sig av en "riktig" databas, t.ex. sqlite. Jag har byggt applikationer som har iaf några hundra tusen rader (inte mkt, men du kommer knappast komma över det i ett sånt här program) som presterar bättre än vad din nuvarande arkitektur gör med så förhållandevis få rader. Men det var kanske inte ditt största problem just nu
2. Läs in filstrukturerna i minnet och jobba mot det istället för att läsa mot hårddisken för varje. Du behöver ju inte loopa dig igenom alla filer heller utan du kan ju få en array med filerna direkt från .net, mycket smidigt. Sen kan du använda dig av linq för att ställa enkla frågor mot listorna. Du behöver inte ta bort filerna som du läst in från listan, det är ganska så tidsödande. Det här är naturligtvis inte det mest omptimala, men det bör vara ganska lite jobb för dig att skriva om och du kommer märka en sjuk skillnad jämfört om du kollar mot hårddisken hela tiden.

Jo, jag vet.. Det där med att ha en XML-fil istället för många är ju något jag tänker ändra på. Plöjer mig igenom en bok nu "Professional C# 2008" och tänkte läsa kapitlet om LINQ to XML innan jag skriver om det... Men är medveten om att det är ett väldigt tidsödande sätt att ha det skrivet :/

Hmm, det där med en databas är ju helt klart intressant... Det som har fått mig att inte göra det är att det ställer krav på att klienten har det installerat?

Hur tänker du att jag ska göra det istället för att ta bort dem från listan? Ha en bool på varje film som är true om den ska vara synlig?

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Citat:

Ursprungligen inskrivet av KurreKula
Hmm, det där med en databas är ju helt klart intressant... Det som har fått mig att inte göra det är att det ställer krav på att klienten har det installerat?

Det underbara med SQLite är ju att det oftast är oinstallerbart, det vill säga att det är en fil du kan arbeta mot/uppdatera oberoende av databasmotorer och hejfadirullan. Det är ett sjukt smidigt sätt om man vill ha en lokal databas hos användare som ändå kan uppdateras över nätet.

Visa signatur

www.uu.se - some kind of university | www.hirr.org.uk - ain't no mountain high enough | www.bajenfans.se

Permalänk
Citat:

Ursprungligen inskrivet av bobamatics
Det underbara med SQLite är ju att det oftast är oinstallerbart, det vill säga att det är en fil du kan arbeta mot/uppdatera oberoende av databasmotorer och hejfadirullan. Det är ett sjukt smidigt sätt om man vill ha en lokal databas hos användare som ändå kan uppdateras över nätet.

Det lät ju helt underbart. Skulle speeda upp det hela en hel del. Men hur är det med om jag vill försöka konvertera det med mono till OSX? Känns som jag bör försöka hålla mig till de inbyggda funktioner som redan finns i .NET då. Ifall jag förbättrar min funktion så att den jobbar med en fel och använder LINQ to XML så borde det bli rätt så snabbt iaf?

Ang mitt ursprungliga problem, hur låter det här:
Nu loopar jag ju igenom alla XML-filer och kollar ifall filen finns. Det jag istället kan göra är ju att innan jag lägger till XML-filen kolla ifall filen finns i listan... Var det så du menade thrawn?

EDIT: Tack!:D Nu skrev jag om det så som jag nämnde sist och nu flyger det förbi

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem
Permalänk
Citat:

Ursprungligen inskrivet av Nexit
http://www.mono-project.com/SQLite

Ojojoj, helt klart nåt jag ska titta på! Håller på och skriver om en hel del kod nu... Insåg att jag hade en jävla massa minnesläckor i programmet... Det tog fan lika mycket minne som visual studio gjorde vilket inte kändes helt rätt :/ Men har fått det att sjunka ordentligt nu... Förut läste jag in bilderna som en cache för att det ska gå snabbare att komma åt dem men det verkar inte vara så stor skillnad i prestanda men ändå så är det ju otroligt mycket mindre att läsa in i minnet.

Ett stort prestandaproblem har blivit att jag nu läser in skådespelare och info om dem också, vilket blir ett par tusen eftersom att det är 5 per film :/ Detta lär dock bli bättre om jag kör SQLite

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av KurreKula

Ang mitt ursprungliga problem, hur låter det här:
Nu loopar jag ju igenom alla XML-filer och kollar ifall filen finns. Det jag istället kan göra är ju att innan jag lägger till XML-filen kolla ifall filen finns i listan... Var det så du menade thrawn?

Precis, nu vet jag ju inte hur du lägger till filmerna i listan om du använder dig av ett DataSource objekt eller lägger till dem manuellt och det funkar ju bara om du lägger till manuellt. Egentligen borde du ju kunna använda dig samma kod som innan och istället för if(File.Exists(file)) så använder du dig av t.ex. filelist.IndexOf(file) eller ett linq-uttryck.

Sen har du somsagt mkt att vinna på med en riktig relationsdatabas. Har själv inte jobbat med annat än System.Data.SQLite 8 men den där mono-wrappern verkar ju helt okej.

Permalänk
Citat:

Ursprungligen inskrivet av thrawn
Precis, nu vet jag ju inte hur du lägger till filmerna i listan om du använder dig av ett DataSource objekt eller lägger till dem manuellt och det funkar ju bara om du lägger till manuellt. Egentligen borde du ju kunna använda dig samma kod som innan och istället för if(File.Exists(file)) så använder du dig av t.ex. filelist.IndexOf(file) eller ett linq-uttryck.

Sen har du somsagt mkt att vinna på med en riktig relationsdatabas. Har själv inte jobbat med annat än System.Data.SQLite 8 men den där mono-wrappern verkar ju helt okej.

Precis, använder mig av ett linq-uttryck för att kolla ifall filen är i listan istället för File.Exists

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase