Zbytečná alokace aneb nevýhody OOP – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Zbytečná alokace aneb nevýhody OOP – .NET – Fórum – Programujte.comZbytečná alokace aneb nevýhody OOP – .NET – Fórum – Programujte.com

 

Matěj Andrle+1
Grafoman
13. 8. 2014   #1
-
0
-

Dobrý den,
chci se jen zeptat, zda v tomto případě dodržovat OOP, či zda mám chybu v návrhu OOP/... Zkrátka mám strukturu, kterážto ve statické funkci Load do nově alokovaného 2D bytového pole vylije bytový soubor.

using System.Windows.Forms;
using System.IO;

namespace Cixu
{
	public struct Map
	{
		const string filter = "MAP files (*.map)|*.map";

		static readonly OpenFileDialog openDialog = new OpenFileDialog()
		{
			Filter = filter,
			DefaultExt = "map",
			AddExtension = true,
			CheckPathExists = true
		};
		static readonly SaveFileDialog saveDialog = new SaveFileDialog()
		{
			Filter = filter,
			DefaultExt = "map",
			AddExtension = true,
			CheckPathExists = true
		};

		public sbyte Direction { get; set; }
		public byte[,] Content { get; set; }
		public int ActiveX { get; set; }
		public int ActiveY { get; set; }

		public static Map Load(int width, int height)
		{
			if (openDialog.ShowDialog() == DialogResult.OK)
			{
				if (new FileInfo(openDialog.FileName).Length == 1601)
					return Load(openDialog.FileName, width, height);
				else
					throw new FileLoadException("Incorrect map file size!");
			}
			else
				throw new System.Exception("Open file dialog aborted!");
		}

		public static Map Load(string fileName, int width, int height)
		{
			Map output = new Map();

			using (BinaryReader bw = new BinaryReader(new FileStream(fileName, FileMode.Open)))
			{
				output.Content = new byte[width, height];
				output.Direction = (sbyte)bw.ReadByte();

				for (int y = 0; y < height; y++)
					for (int x = 0; x < width; x++)
					{
						byte value = bw.ReadByte();
						output.Content[x, y] = value;

						if ((value & 240) == 16)
						{
							output.ActiveX = x;
							output.ActiveY = y;
						}
					}

				return output;
			}
		}

		public static void Save(int width, int height, byte[,] map, sbyte direction)
		{
			if (saveDialog.ShowDialog() == DialogResult.OK)
				Save(saveDialog.FileName, width, height, map, direction);
		}

		public static void Save(string fileName, int width, int height, byte[,] map, sbyte direction)
		{
			using (BinaryWriter bw = new BinaryWriter(new FileStream(fileName, FileMode.Create)))
			{
				bw.Write((byte)direction);

				for (int y = 0; y < height; y++)
					for (int x = 0; x < width; x++)
						bw.Write(map[x, y]);
			}
		}
	}
}


Zde tedy dochází k neustálé alokaci místa v RAM. Přitom kdybych to vyléval rovnou do cílové proměnné, alokace by proběhla jednou jedinkrát. Obdobný probém mám i na jiných místech programu. Řeším to, poněvadž se nyní data k načtení budou kupit - přidávám další pomocné bitové mapy. (asi to nakonec sloučím do jednoho formátu) A tak si říkám - co třeba hodit referenci?
Děkuji.

Nahlásit jako SPAM
IP: 78.136.161.–
KIIV
~ Moderátor
+43
God of flame
13. 8. 2014   #2
-
0
-

tak kdyz pouzivas samy staticky metody, tak se prirozene musi hodne kopirovat... nejprve instanci mapy a pak nad ni zavolal load, tak to nahrajes rovnou tam (nebo dokonce pouzit konstruktor, kterymu bys predal jmeno mapy)

(to co tady pouzivas je spis ukazka "proceduralniho programovani v oop")

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Matěj Andrle+1
Grafoman
13. 8. 2014   #3
-
0
-

#2 KIIV
Nechápeš. Nepotřebuji instanci! To, kam to potřebuji vylít, je jedna jediná proměnná. A právě kvůli OOP, jsem musel udělat jinak zbytečnou strukturu... (samozřejmě jsem to udělal i kvůli tomu, abych se v dané třídě vyznal) Do té jedné proměnné tedy dávám stále nové instance - když by stačila jedna jediná. A proto mi přijde logické, dát jen referenci na ni. Ovšem celé toto vlákno točím kolem OOP...

Nahlásit jako SPAM
IP: 78.136.161.–
KIIV
~ Moderátor
+43
God of flame
13. 8. 2014   #4
-
0
-

instance tak jak tak vyrabis tim new Map() takze moc nechapu o co se snazis...

pokud chces jedinou kopii dat, tak pouzij singleton - ikdyz si moc nedokazu predstavit, ze bys mel jedinou mapu

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Matěj Andrle+1
Grafoman
13. 8. 2014   #5
-
0
-

#4 KIIV
Nejde mi o instanci mapy - to už jsem v OOP vzdal řešit... :D Řeším datové pole - byte 2D... To mi přijde zbytečné tolikrát zakládat kdesi v paměti, když to mohu mít na jednom jediném místě - stačí akorát přepisovat hodnoty....

Nahlásit jako SPAM
IP: 78.136.161.–
Ovrscout
~ Anonymní uživatel
113 příspěvků
14. 8. 2014   #6
-
0
-

Tys tím pracuješ spíše jako se strukturou kterou předáváš do funkcí Load/Save.

Pokud nechceš pořád kopírovat/alokovat tak nejdřív jednorázově vytvoř instanci objektu Map (
Map mojemapa = new Map();),
a poté nad touto instancí volej funkce load/save (ale ne static public ale jen public funkce)
které pracují přímo s dannou instancí, takže ten objekt nemusíš předávat dovnitř/ven ale přímo s ním pracuješ:
  -  mojemapa.Load(string fileName, int width, int height)
     {this.Content = new byte[width, height];..}; //nebo bez "this."
  - mojemapa.Save(string fileName, int width, int height, sbyte direction);
  - mojemapa.content ..

Detaily se pak můžou různě lišit, např jestli dovolíš jen jeden load(a s tím spojenou alokaci content) nebo umožníš více loadů a budeš content používat opakovaně(nebo ho přealokuješ pokud nebude dost velký), load v konstruktoru atd atd.

Také mi přijde že dialogová okna pro výběr souboru by mohla být někde jinde (v hlavním objektu fromuláře/okna/aplikace) a tuhle třídu nechat jen uchovávat, zpracovávat a načítat/ukládat data.
Ale to už záleží i na zbytku tvého projektu.

P.S. Jeste bude asi potreba dopnit konstruktor a destruktor pro inicializaci a uvolneni pameti(Content)
P.P.S. nejsem zrovna c# ani oop guru, tak to ber z rezervou, a radši koukni do nějaké pěkné knížky

Nahlásit jako SPAM
IP: 193.165.79.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 2 hosté

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý