Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / Forum översikt / inlägg

Posta nytt inlägg


Konvertera ett värde till timmar, minuter och sekunder

Postades av 2007-05-07 14:03:42 - Pelle Johansson, i forum c# (c-sharp), Tråden har 29 Kommentarer och lästs av 2445 personer

Optimeringar är en utmanande fråga. I detta exempel matas mm:ss in i ett fält och skall omvandlas till 100-delar i sekunder för att mottagande system behöver detta format. Frågan är - hur skulle ni skriva denna kod så optimerat som möjligt? Indata är mm:ss, utdata är m,ss.

Exempel:

  string varde = ConvertMinSekToHundreds("2:36")
  varde = "2,60"


Och funktionen:

public string ConvertMinSekToHundreds(string thetime) {

        char[] sep = {':'};
        Array tmp = thetime.Split(sep);

        string min = "";
        decimal s = 0;
        decimal sec = 0;

        if (tmp.Length >0) {
            min = tmp.GetValue(0).ToString() ;
            s = Convert.ToDecimal(tmp.GetValue(1).ToString());
            sec = (s * 100)/60; //sec = (s /60d) * 100d;
        } else {
            return "0,0";
        }

        return min + ',' + sec.ToString();

    }


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 15:17:43 - Andreas Hillqvist

Jag vet inte om den är optimerad, men lite snabare kanske den är:

        public string ConvertMinSekToHundreds(string thetime) 
        {
            int pos = thetime.LastIndexOf(':');
            if (pos != -1)
            {
                int s = int.Parse(thetime.Substring(pos+1));                            
                int sec = (s * 100) / 60; //sec = (s /60d) * 100d;
                return thetime.Substring(0, pos) + ',' + sec.ToString();
            } 
            else 
            {
                return "0,0";
            }
        }

Jag antar att LastIndexOf är snabbare en split, då en splitt inte vet hur många värden som finns. Borde ge den lite over head.
Jag antar oxå att Substring() är relativt snabb. Alokera minne för strängen, kopiera över text.
Heltal borde vara snabbare än decimal.
Att anropa toString() på en sträng är ju helt onödigt.
Om ett kollon(:) saknas behöver ju inga variabler deklareras eller tilldelas.
Tilldelar inga defaultvärden då det är onödigtm men detta borde kanske kompilatorn optimera bort.


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 15:20:55 - Johan Idstam

Ska den göra rätt också?

Om man skickar in 2:01 får man inget roligt resultat:

2,1,6666666666666666666666666667

/johan/


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 15:37:51 - Pelle Johansson

Ja, den skall göra rätt också :) . 2 decimaler max.


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 16:27:54 - Daniel Hermansson

Hur kommer indatan se ut. "mm:ss" betyder för mig att det alltid kommer vara två siffror som beskriver både minuter och sekunder. tex 05:08. I så fall behövs inte LastIndexOf(':') utan man kan alltid sätta positionen till 2. Andreas (och min innan jag såg hans) som använder heltal räknar fel på en del tider också. Tex 02:34 "avrundas" felaktigt till 2,56 som bör vara 2,57.

Min lösning blev ganska precis som Andreas därför postar jag inte den. Men man behöver inte två int för sekunderna.

int s = int.Parse(thetime.Substring(pos+1));                            
int sec = (s * 100) / 60;
---------
int s = int.Parse(thetime.Substring(pos+1));                            
s = (s * 100) / 60;


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 17:29:18 - Pelle Johansson

Kunden kan skriva 2:25, 2:45 3:00 osv osv..


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 18:49:18 - Simon Dahlbacka

Om man profilerar dom olika förslagen, så är Pelles förslag sämst, sen följer Daniels variation av Andreas förslag, och snabbast hittills verkar den här varianten vara:

EDIT: metoden skall naturligtvis vara statisk...

        public static string ConvertMinSekToHundreds(string thetime)
        {
            int pos = thetime.LastIndexOf(':');
            if (pos != -1)
            {
                int s = int.Parse(thetime.Substring(pos + 1));
                s = (s * 100) / 60;

                return thetime.Substring(0, pos) + "," + s.ToString();
            }
            else
            {
                return "0,0";
            }
        }


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 20:15:04 - Jonas Ekström

Här har du en riktigt långsam, men med mindre kod:

<code>
public static string ConvertMinSekToHundreds(string t)
{
DateTime d = DateTime.Parse((t.ToString().Contains(":") ? "00:" : "00:00:") + t);
return string.Format("{0:00},{1:00}", d.Minute, d.Second * 1.67);
}
</code>


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 21:19:08 - Daniel Hermansson

Jonas är den ända som ger rätt resultat på tider som ska avrundas uppåt.
Har ni något som kan mäta tiden som en metod kör eller är det gissningar och antagande ni gjort tidigare tråden?


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 21:40:17 - Simon Dahlbacka

<b>Jonas är den ända som ger rätt resultat på tider som ska avrundas uppåt. </b>
Jasså, care to give an example..?

<b>Har ni något som kan mäta tiden som en metod kör eller är det gissningar och antagande ni gjort tidigare tråden?</b>
Jag har åtminstone använt profilern som finns i VS (>= team edition developer)


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 21:50:31 - Daniel Hermansson

2:34 ger 2,56 men bör avrundas till 2,57


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 22:45:19 - Simon Dahlbacka

Ok, den här borde väl ge korrekt resultat (och är fortfarande snabbast enligt mina test..)

        public static string ConvertMinSekToHundreds(string thetime)
        {
            int pos = thetime.LastIndexOf(':');
            if (pos != -1)
            {
                int s = int.Parse(thetime.Substring(pos + 1));
                s = (s * 100 + 30) / 60;

                return thetime.Substring(0, pos) + "," + s.ToString();
            }
            else
            {
                return "0,0";
            }
        }


Här är lite rådata, 99999 anrop, enhet ms
<code>
Function Incl children
Pelle 255.6 1032.4
Jonas 188.7 1291.5
Simon 123.4 372.1
</code>


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 22:49:17 - Erik Näslund

Jag har jämfört mot Simons funktion som helt klart var snabb.

Testning gjordes med GetTickCount() i C och Environment.TickCount i C#. TickCount sparades före och efter funktionens start resp slut. Differensen mellan StartCount och EndCount är de värden jag redovisar.

En miljon iterationer av koden tog ca 750ms på min dator. Bara för att testa skrev jag samma sak i C, och med string.h var C-versionen endast några få millisekunder snabbare. Troligtvis skulle detta gå att förbättra en hel del med intelligentare minneshantering, precis som C# gör.

Efter lite optimering fick jag dock ner C-versionen på ca 250ms, vilket är 3 ggr så snabbt som i C#.
Jag kan lova att den optimerade versionen inte hade direkt hög läsbarhet, men den var snabb iallafall.

Om du hör till de människor som översätter mellan olika tidsformat miljarder gånger per dag kan sån här optimering vara intressant. I övrigt känns det som det är bättre att satsa på läsbar kod samt att lära sig en profiler för att identifiera hotspots som faktiskt lämpar sig för optimering.


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 22:56:40 - Andreas Hillqvist

Jag har ett nytt alternativ vilket förutsätter korrekt input M:SS där SS är tvåsiffrig och inte överstiger 59:

        private static char[] minutesAsDecimal = new char[] { 
            '0', '0', // 0
            '0', '1', // 1
            '0', '3', // 2
            '0', '5', // 3
            '0', '6', // 4
            '0', '8', // 5
            '1', '0', // 6
            '1', '1', // 7
            '1', '3', // 8
            '1', '5', // 9
            '1', '6', //10
            '1', '8', //11
            '2', '0', //12
            '2', '1', //13
            '2', '3', //14
            '2', '5', //15
            '2', '6', //16
            '2', '8', //17
            '3', '0', //18
            '3', '1', //19
            '3', '3', //20
            '3', '5', //21
            '3', '6', //22
            '3', '8', //23
            '4', '0', //24
            '4', '1', //25
            '4', '3', //26
            '4', '5', //27
            '4', '6', //28
            '4', '8', //29
            '5', '0', //30
            '5', '1', //31
            '5', '3', //32
            '5', '5', //33
            '5', '6', //34
            '5', '8', //35
            '6', '0', //36
            '6', '1', //37
            '6', '3', //38
            '6', '5', //39
            '6', '6', //40
            '6', '8', //41
            '7', '0', //42
            '7', '1', //43
            '7', '3', //44
            '7', '5', //45
            '7', '6', //46
            '7', '8', //47
            '8', '0', //48
            '8', '1', //49
            '8', '3', //50
            '8', '5', //51
            '8', '6', //52
            '8', '8', //53
            '9', '0', //54
            '9', '1', //55
            '9', '3', //56
            '9', '5', //57
            '9', '6', //58
            '9', '8', //59
        };

        static public string ConvertMinSekToHundreds(string thetime) 
        {
            char[] data = thetime.ToCharArray();
            int length = data.Length;
            int s = (data[length-2]*10) + data[length-1] - 528;
            s *= 2;
            data[length - 1] = minutesAsDecimal[s + 1];
            data[length - 2] = minutesAsDecimal[s];
            data[length - 3] = ',';
            return new string(data);
            
        }

Vet inte om den är snabbare. Men jag tror den borde vara det.

Vill man avrunda upåt så är det bara att uppdatera arrayen. Vill bara visa principen.

Finns risk att den är lite långsamare än något man kan göra i C. Just för att man arbetar med objekt.


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 23:00:27 - Daniel Hermansson

Edit: jahapp...Andreas var på samma spår och var visst några minuter före :)

Nu har jag fått till en ny version som är lite olik de andra.
Den är optimerad med tanka på tid och inte minne och bör vara aningen snabbare än Simons.

private static int[] lut = {0, 2, 3, 5, 7, 8, 10,
                                12, 13, 15, 17, 18, 20,
                                22, 23, 25, 27, 28, 30,
                                32, 33, 35, 37, 38, 40,
                                42, 43, 45, 47, 48, 50,
                                52, 53, 55, 57, 58, 60,
                                62, 63, 65, 67, 68, 70,
                                72, 73, 75, 77, 78, 80,
                                82, 83, 85, 87, 88, 90,
                                92, 93, 95, 97, 98};

        public static string ConvertMinSekToHundreds(string thetime)
        {
            int pos = thetime.LastIndexOf(':');
            if (pos == -1)
                return "0,00";
            return thetime.Substring(0, pos) + ',' + lut[int.Parse(thetime.Substring(pos + 1))];
        }


Hittade även en bugg i Jonas version också. Den ger fel värden på sekunderna om de skrivs med en nolla först. 15:05 ger 15,08 vilket borde vara 15,8.


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 23:06:10 - Andreas Hillqvist

Jävlar, min kod har nog samma "fel" som Jonas.

Men jag kan inte förstå hur fem minuter bör vara 0,8.
5 minuter (0,08) är ju mindre än 48 minuter (0,8).

Frågan är om man tjänar något på att optimera bort split() och int.Parse() och toString().


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-07 23:32:09 - Daniel Hermansson

Nu har jag testat lite med Environment.TickCount som Erik nämner. Min var visst ordentligt långsam :) Ställer mig lite vid sidan av tråden och skäms...

Andreas och Jonas: glöm det jag skrev om felet i Jonas funktion. Jag vet inte hur jag tänkte och jag tror det betyder att min räknar fel nu.


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-08 00:04:15 - Simon Dahlbacka

Jahapp där ser man. Daniels är marginellt snabbare än min, däremot är din Andreas dubbelt och inte långt ifrån tredubbelt snabbare, så ja, Parse/ToString är inge vidare, Split inte heller (Substring inte lika farligt btw)

(Sen är det ju en annan femma hur mycket det är värt att optimera..)

Andreas
System.String..ctor(char[]) 99999 37.102189 37.102189 37.102189 37.102189
System.String.ToCharArray() 99999 14.424489 14.424489 14.424489 14.424489

Daniel
System.String.Concat(object,object,object) 99999 103.406767 103.406767 103.406767 103.406767
System.Int32.Parse(string) 99999 41.113222 41.113222 41.113222 41.113222
System.String.LastIndexOf(char) 99999 19.465046 19.465046 19.465046 19.465046
System.String.Substring(int32) 99999 15.921165 15.921165 15.921165 15.921165
System.String.Substring(int32,int32) 99999 15.425451 15.425451 15.425451 15.425451

Simon
System.String.Substring(int32) 99999 63.405950 63.405950 63.405950 63.405950
System.Int32.Parse(string) 99999 43.684979 43.684979 43.684979 43.684979
System.Int32.ToString() 99999 40.745828 40.745828 40.745828 40.745828
System.String.Substring(int32,int32) 99999 35.071989 35.071989 35.071989 35.071989
System.String.Concat(string,string,string) 99999 32.616640 32.616640 32.616640 32.616640
System.String.LastIndexOf(char) 99999 12.709621 12.709621 12.709621 12.709621

Daniel 2 (se nedan)
System.String.Substring(int32,int32) 99999 39.863986 39.863986 39.863986 39.863986
System.Int32.Parse(string) 99999 37.033350 37.033350 37.033350 37.033350
System.String.Concat(string,string,string) 99999 22.287204 22.287204 22.287204 22.287204
System.String.Substring(int32) 99999 18.941672 18.941672 18.941672 18.941672
System.String.LastIndexOf(char) 99999 14.520839 14.520839 14.520839 14.520839

Baserat på profileringen av Daniels kod testade jag med följande: (som Daniel2 ovan)

        private static string[] lut2 = {"0", "2", "3", "5", "7", "8", "10",
                                "12", "13", "15", "17", "18", "20",
                                "22", "23", "25", "27", "28", "30",
                                "32", "33", "35", "37", "38", "40",
                                "42", "43", "45", "47", "48", "50",
                                "52", "53", "55", "57", "58", "60",
                                "62", "63", "65", "67", "68", "70",
                                "72", "73", "75", "77", "78", "80",
                                "82", "83", "85", "87", "88", "90",
                                "92", "93", "95", "97", "98"};

        public static string Daniel2ConvertMinSekToHundreds(string thetime)
        {
            int pos = thetime.LastIndexOf(':');
            if (pos == -1)
                return "0,00";
            return thetime.Substring(0, pos) + "," + lut2[int.Parse(thetime.Substring(pos + 1))];
        }


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-08 00:06:55 - Ola Lindfeldt

Ännu snabbare är att förbereda alla 3600 kombinationer av värden som strängar från
"00:00" till "59:59" i en Hashtable och sedan slå upp i den.
Jag får ca 125 ms på en miljon iterationer.


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-08 00:19:24 - Simon Dahlbacka

Låter troligt att det är snabbare, men som sagt, hur mycket är det värt att optimera?
Den koden är något tråkig att skriva och sedan felsöka om man töntat till det hela..


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-08 10:20:08 - Pelle Johansson

Först måste jag säga att givetvis var inte min kod snabbast - då hade ni ju inte kunnat briljera som ni gjort här med undersökningar, tester och energi. Bra jobbat! Jag tror att många kan vara intresserade av såna här typer av frågeställningar. Just i mitt fall så behövs ingen optimerad rutin, men betänk att det hade lika gärna kunnat vara en omräkning på 1 miljon poster och då hade varenda millisekund räknats som dyrbar.

Bra utredning och bra jobbat. Skicka gärna in flera liknande diskussioner så kanske vi kan ha ett forum som heter nåt i stil med just kodoptimering eller liknande där vi kan påvisa dessa stora differanser.

Har någon tid så kan ni ju även omsätta en sån här tråd till en artikel vilket är både nyttigt och lärorikt.

//Pelle


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-08 11:02:52 - Simon Dahlbacka

<b>Har någon tid så kan ni ju även omsätta en sån här tråd till en artikel vilket är både nyttigt och lärorikt.</b>
Jag kan nog göra det, dock skulle det vara bättre att i så fall använda sej av nån fri/gratis profiler (om nån sån finns), iom att "kundkretsen" är något liten om det krävs >= Team Edition Developer av Visual Studio, dessutom har antagligen denna lilla kundkrets redan koll på detta område?

Men som sagt.. tänker/vill nån annan göra det, så säg bara till...


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-08 15:07:44 - Oskar Johansson

> Men som sagt.. tänker/vill nån annan göra det, så säg bara till...

Oavsett vem som skriver så vill jag läsa :P


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-09 12:31:16 - Pelle Johansson

Skriv du Simon, det blir kanoners!


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-09 13:35:17 - Lars Gottfridsson

En fråga bara:
Är det nån som har nån uppfattning vilken prestandaförbättring man skulle
kunna uppnå om man använder sig av ( unmanaged code / assembler ) i
detta fall?


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-05-09 14:39:56 - Simon Dahlbacka

misstänker att det där är för liten snutt för att unmanaged/assembler ska ha nån större betydelse...


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-05-09 18:45:49 - Simon Dahlbacka

ok.. har börjat lite smått, men "don't hold your breath" :-)


Svara

Sv:Optimerad funktion - någon som kan bättre?

Postades av 2007-06-28 23:24:54 - Pelle Johansson

Var några veckor sen, har du kommit någonstans?

Jag skrev en annan nu som verkar fungera ganska bra.

       static void Main(string[] args)
        {

            int x = 510;
            string y = ConvertToTime(x);
            Console.WriteLine("x är {0} och konverterat är värdet {1}", x, y);
        }

        static string ConvertToTime(int TotalSeconds)
        {
            int Hours, Seconds, Minutes;

            Hours = TotalSeconds / 3600;
            TotalSeconds -= Hours * 3600;
            Minutes = (TotalSeconds / 60);
            Seconds = TotalSeconds - Minutes * 60;

            return Minutes.ToString().PadLeft(2, '0') + ":" + Seconds.ToString().PadLeft(2, '0');
        }


Svara

Sv: Optimerad funktion - någon som kan bättre?

Postades av 2007-06-29 08:09:57 - Simon Dahlbacka

<b>Var några veckor sen, har du kommit någonstans?</b>

Angående artikeln menar du?

Jo har nog kommit en bra bit, men har ett par grejer jag vill ha med ännu. Tyvärr har jag inte hunnit/orkat skriva den klar, men förhoppningsvis "den som väntar på något gott..." :-D


Svara

Nyligen

  • 19:55 kick-off med fokus på hälsa?
  • 19:53 kick-off med fokus på hälsa?
  • 16:24 Föreslå en skönhetsklinik online
  • 16:23 Föreslå en skönhetsklinik online
  • 18:42 Hvor finder man håndlavede lamper
  • 18:41 Hvor finder man håndlavede lamper
  • 16:36 Allt du behöver veta om keramiskt
  • 16:14 Vem anlitar man egentligen när tak

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 570 718
27 958
271 751
3 276
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies