Utworzenie daty na podstawie ciągu znaków

0

Jak w ładny sposób z ciągu np. 140927 r/m/d utworzyć datę 2014.09.27 ? Może

Stringbuilder

albo

DateTime

ale za ładnie/wydajnie to mi się nie wydaje że to będzie. Ten ciąg jest wczytywany z pliku txt.

0

Może tak:

 
  string sth = "140927";
  var dt = DateTime.ParseExact( sth,"yyMMdd", CultureInfo.InvariantCulture);
0

Krótszy kod, ale wydajność gorsza od Stringbuildera.

0

Ale co dokładnie chcesz osiągnąć? Wklej swój kod. Chcesz datę czy string daty?

0

string.

Potrzebuję tylko jednę datę. Mniej więcej coś takiego:

 StringBuilder sb = new StringBuilder("20");        
 sb.Append(List[List.Count - 1].Substring(0, 2));
 sb.Append(".");
 sb.Append(List[List.Count - 1].Substring(2, 2));
 sb.Append(".");
 sb.Append(List[List.Count - 1].Substring(4, 2));
 return sb.ToString(); 
0

Krótszy kod, ale wydajność gorsza od Stringbuildera.
Robisz to milion razy że ma znaczenie?

0

Jeżeli chodzi o sam string, dalsza optymalizacja nie ma już większego sensu. Zamiast substring możesz użyć bezpośredniego odwołania elementów, ale to są dziesiątki ms przy millionie powtórzeń, więc gra nie warta świeczki.
Jeżeli natomiast nie zależy Ci na zmniejszaniu czasu wykonania, a nie chcesz robić tego przez podaną metodę z DateTime, żeby kod był czytelniejszy możesz użyć np.:

      StringBuilder sb = new StringBuilder();
                var dt = sb.AppendFormat("20{0}.{1}.{2}",
                                        z.Substring(0, 2), 
                                        z.Substring(2, 2),
                                        z.Substring(4, 2)).ToString();

 
0

@mkr: no to StringBuilder staje się w ogóle niepotrzebny:

var dt = String.Format("20{0}.{1}.{2}",
                      z.Substring(0, 2), 
                      z.Substring(2, 2),
                      z.Substring(4, 2));
2

To może tak:

var dt = string.Format("20{0}{1}.{2}{3}.{4}{5}",
            z[0], z[1], z[2], z[3], z[4], z[5]);

:D

0

@_13th_Dragon gdzie popełniam błąd w swoim myśleniu:

class TestClass
    {
        public List<string> Base { get; set; }
        public TestClass()
        {
            this.Base = new List<string>();
            GenFakeBase();            
        }

             public void FormatStringTest()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            foreach (var z in this.Base) {
                var dt = String.Format("20{0}.{1}.{2}",
                                       z.Substring(0, 2),
                                       z.Substring(2, 2),
                                       z.Substring(4, 2));
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed);
        }

      
        public void StringBuilderFormatTest()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            foreach (var z in this.Base)
            {
                StringBuilder sb = new StringBuilder();
                var dt = sb.AppendFormat("20{0}.{1}.{2}",
                                        z.Substring(0, 2), 
                                        z.Substring(2, 2),
                                        z.Substring(4, 2)).ToString();
           
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed);
        }
     
        private void GenFakeBase()
        {
            Random r = new Random();
          
            for (int i = 0; i < 4000000; i++)
            {
                this.Base.Add(String.Format("{0:yyMMdd}",
                              new DateTime(r.Next(2000, 2099), r.Next(1, 12), r.Next(1, 25))));
            }                         
            
        }
    }
 

Output:

 
FormatStringTest: 00:00:00.6319586
StringBuilderFormatTest: 00:00:00.6164244

Edit:
Wytłumaczenie dlaczego:
http://stackoverflow.com/a/6824

1
mkr napisał(a):

@_13th_Dragon gdzie popełniam błąd w swoim myśleniu:

  1. Jeżeli podajesz testy to podawaj tak aby można było odpalić
  2. Na starcie program dostaje nieco mniej czasu systemowego ponieważ zostaje mu policzony sam start (ładowanie do pamięci) więc pierwszy wynik zawsze gorszy
  3. Aby coś mówić o czasach musisz mieć czasy liczone w minutach lub zrobić przynajmniej 10 pomiarów i je uśrednić.

http://ideone.com/O365uh

2

FormatStringTest: 0000.6319586
StringBuilderFormatTest: 0000.6164244

To jest 2% różnica w granicy błędu pomiaru. Patrz na to:

FormatStringTest:
00:00:05.5449600
00:00:05.4707517
00:00:05.0750559

StringBuilderFormatTest:
00:00:04.4070724
00:00:04.3707764
00:00:04.3315935

To już jest 20-procentowa różnica.

.NET 3.5 na Pentium 4 (2.4 GHz), system 32-bitowy

0

Jeżeli string.Format wykorzystuje StringBulider.AppendFormat to jak może być szybsze, skoro dodatkowo sprawdza warunki i wykonuje operacje arytmetyczne?
Pytam bo nie wiem.

Na mojej konfiguracji test @_13th_Dragon, dla 10mln:

StringBuilderFormatTest: 00:00:01.5849949
FormatStringTest: 00:00:01.6064279
StringBuilderFormatTest: 00:00:01.5818493
FormatStringTest: 00:00:01.6310405
StringBuilderFormatTest: 00:00:01.5696752
FormatStringTest: 00:00:01.6012421
StringBuilderFormatTest: 00:00:01.5687627
FormatStringTest: 00:00:01.5957641
StringBuilderFormatTest: 00:00:01.5678932
FormatStringTest: 00:00:01.5968718
StringBuilderFormatTest: 00:00:01.5839259
FormatStringTest: 00:00:01.5899373
StringBuilderFormatTest: 00:00:01.5626319
FormatStringTest: 00:00:01.6167412
StringBuilderFormatTest: 00:00:01.5615933
FormatStringTest: 00:00:01.6005508
StringBuilderFormatTest: 00:00:01.5598783
FormatStringTest: 00:00:01.6258477
StringBuilderFormatTest: 00:00:01.5630360
FormatStringTest: 00:00:01.6113027
 

Nadal utrzymuję, że na mojej konfiguracji jest StrinBuilder.AppendFormat() nieznacząco szybszy :)
Oczywiście wiem, że ta rozmowa nie ma sensu praktycznego i nikt nie patrzy na ms przy 10mln operacji.

0
Azarien napisał(a):

FormatStringTest: 0000.6319586
StringBuilderFormatTest: 0000.6164244

To jest 2% różnica w granicy błędu pomiaru. Patrz na to:

FormatStringTest:
00:00:05.5449600
00:00:05.4707517
00:00:05.0750559

StringBuilderFormatTest:
00:00:04.4070724
00:00:04.3707764
00:00:04.3315935

To już jest 20-procentowa różnica.

.NET 3.5 na Pentium 4 (2.4 GHz), system 32-bitowy

czemu uwazasz ze jest to blad pomiaru? StopWatch to chyba QueryPerformanceCounter a tam dokladnosc jest bardzo duza

0

czemu uwazasz ze jest to blad pomiaru?
Bo nie robi się pomiarów czasu, jeśli różnica jest rzędu setnych sekundy.

Jeżeli string.Format wykorzystuje StringBulider.AppendFormat to jak może być szybsze, skoro dodatkowo sprawdza warunki i wykonuje operacje arytmetyczne?

Bo AppendFormat() używa StringBuildera, ale nie robi new StringBuilder(), tylko najwyraźniej pobiera z jakiejś puli wcześniej utworzonych StringBuilderów:

            StringBuilder sb = StringBuilderCache.Acquire(format.Length + args.Length * 8);
            sb.AppendFormat(provider,format,args);
            return StringBuilderCache.GetStringAndRelease(sb);

Dlaczego tak to zrobili? Trudno powiedzieć. Może chodziło o prędkość (u nich tak było szybciej, u ciebie nie), a może o unikanie alokacji pamięci i obciążanie garbage collectora.

1 użytkowników online, w tym zalogowanych: 0, gości: 1