Diskuze: Obě zarovnání
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 17 zpráv z 17.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Není to ještě ideální, ale řešení již mám:
using System;
namespace ConsoleExtra.Controls
{
public enum Align
{
Left = 0,
Center = 1,
Right = 2
}
public class MessageBox
{
private static string Equally(string text, int lineLength, string whiteSpaceLine, Align textAlign)
{
return String.Format("{0," + lineLength + "}", text + whiteSpaceLine.Substring(text.Length + ((int)(0.5F * (float)textAlign * (lineLength - text.Length)))));
}
public static void Show(string text)
{
Show(text, " █ ", Align.Center);
}
public static void Show(string text, Align textAlign)
{
Show(text, " █ ", textAlign);
}
private static void WriteLine(int tab, string text)
{
Console.CursorLeft = tab;
Console.WriteLine(text);
}
public static void Show(string text, string border, Align textAlign)
{
int length,
fullLength,
margin = Console.WindowWidth - 20,
tab = (Console.WindowWidth - (margin + 2 * border.Length)) / 2;
string whiteSpaceLine = new string(' ', margin),
startLine = border + Equally(" ", margin, whiteSpaceLine, textAlign) + border,
endLine;
fullLength = startLine.Length;
Action writeText = delegate() { WriteLine(tab, startLine); };
for (int start = 0; start < text.Length; start += length + 1)
{
try
{
length = text.Substring(start, margin).LastIndexOf(' ');
if (length == -1)
length = margin;
}
catch
{
length = text.Length - start;
}
string line = border + Equally(text.Substring(start, length), margin, whiteSpaceLine, textAlign) + border;
fullLength += line.Length;
writeText += delegate() { WriteLine(tab, line); };
}
Console.ForegroundColor = ConsoleColor.Black;
Console.BackgroundColor = ConsoleColor.Gray;
endLine = border + Equally(" ", margin, whiteSpaceLine, textAlign) + border;
fullLength += endLine.Length;
writeText += delegate() { WriteLine(tab, endLine); };
Console.CursorTop = (Console.WindowHeight - fullLength / (margin + 2 * border.Length)) / 2;
writeText();
Console.ResetColor();
}
}
}
Už jsem ti to psal někde jinde - nespojuj stringy pomocí +. Podívej se na StringBuilder http://msdn.microsoft.com/…builder.aspx a na string.Format http://msdn.microsoft.com/….format.aspx (ten koukám někdy používáš, nechápu teda proč ne vždycky?)
Dál, když někde používáš stringové konstanty (" █ ", " " ...), měl bys je mít taky jako konstanty nadeklarované, jinak úplně zbytečně děláš pořád nové instance Stringu (možná to zoptimalizuje kompiler, ale nespoléhal bych na to).
Jako poslední bych zase doporučil schovat si "výkonný" kód za interface
a ten tvůj MessageBox (imho ne moc dobře zvolené jméno třídy, která
píše do konzole, ale co už) tahat přes nějakou factory. Budeš tím mít
šanci v budoucnu implementovat nějaká lepší řešení, což by dle mého
mělo přijít
Dokud nespojuje více než cca 5 stringů, tak ať klidně používá +, rychlostně to vychází nastejno, až u většího množství se začne projevovat výhoda stringbuilderu.
Border není konstanta - jelikož každý box může mít svůj okraj - jen dělám defaultní hodnoty, když uživateli bude záležet jen na některých faktech. StringBulider/Format jsou jen hezky zabalené objekty - když nepotřebuji nic speciálního, co již za mne tyto objekty vyřešily, nevidím důvod jejich používání.
Zbytečné inicializace a jiné konstrukce byly již dávno smazány - jak jsem psal - teprve jsem dořešil onen problém - ale bylo již hodne pozdě, takže dál jsem pokračval ráno. Celé jsem to pořádně pročistil.
OOP pojmenovávání je geniálni v tom, že pro každý objekt budou platit stejné názvy... Viz. funkce Text pro všechny Fomrs.Control. Chci dělit - cokoliv - bude to vždy Split, chci to a to - bude to vždy to a to... Rozdíl bude jen v namespace/třídě...
EDIT:
Ano - kdybych měl skutečně co stavět - rozsáhlý text, řeším to jinak - ale tady skoro o nic nejde...
Na těch pár stringů je to fuk, optimalizace je v daném případě zbytečná.
Počkat, měl jsem dojem, že to má být vypisování obsahu HTML dokumentů do konzole. Tak jestli zrovna to je "pár stringů"... Můžu se optat, kde jsi vzal těch "cca 5 stringů"? Netvrdím, že to není pravda, ale zajímalo by mě, jestli to je jen odhad, nebo co?
Dokud to nejsou megabajty dat, tak je to fakt jedno. Dokumenty HTML bývají poměrně krátké.
Zkoušel jsem spojit 200 jednoznakových Stringů a tam plus trvalo dvojnásobek času než stringbuilder.
Teď jsem zkoušel "realističtější" obsahy stringů (a menší počet spojování) a vyhrává jednoznačně plus:
private void test()
{
int words = 1000000;
String[] strings = new String[5] { "Ahoj", "", "Úžasně žluťoučký kůň pěl ďábelské ódy", "x", "Nějaký text" };
String testString;
// Plus
DateTime now = DateTime.Now;
testString="";
for (int i = 0; i < words; i++)
{
testString = strings[0] + strings[1] + strings[2] + strings[3] + strings[4];
}
DateTime then = DateTime.Now;
this.Text = "Plus: " + (then - now).TotalMilliseconds + "ms";
// Builder
now = DateTime.Now;
testString="";
for (int i = 0; i < words; i++)
{
StringBuilder sb = new StringBuilder();
sb.Append(strings[0]);
sb.Append(strings[1]);
sb.Append(strings[2]);
sb.Append(strings[3]);
sb.Append(strings[4]);
testString = sb.ToString();
}
then = DateTime.Now;
this.Text += ", Builder: " + (then - now).TotalMilliseconds + "ms";
// Format
now = DateTime.Now;
testString = "";
for (int i = 0; i < words; i++)
{
testString = String.Format("{0}{1}{2}{3}{4}", strings[0], strings[1], strings[2], strings[3], strings[4]);
}
then = DateTime.Now;
this.Text += ", Format: " + (then - now).TotalMilliseconds + "ms";
}
Plus: 187,0107ms
Builder: 301,0172ms
Format: 433,0248m
Concat mi teď vyšel stejně rychlý jako sčítání pomocí plusů
Nejlepší na tom je jak mne tu napadáte (celkově), ale sami jste s řešením nepřišli - já ano a jak se ukazuje, nebyl důvod tu diskutovat - a jak jsem psal - to jsem to navíc osekal, přehodil do ještě obecnějšího objektu a zbavil se dalšího náročného elementu (deklaruji jen jednoho delegáta, kterému definuji příkazy souhrnně) - nyní je tam to nejnáročnější jen ten cyklus.
Ale nebreč, tak jsem holt neměl pravdu, Kit mi ukázal proč a je to.
Nechci tady exhumovat jedno už skoro zapomenuté vlákno, kdy se ti stalo
totéž, ale tak šťastně to nedopadlo
EDIT: teda spíš Satik, pardon
Na rozdíl od tebe tu (snad) všichni umíme přiznat svou chybu
Zobrazeno 17 zpráv z 17.