Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Speed up code

Speed up code

Scheduled Pinned Locked Moved C#
helpdebuggingperformance
13 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Sascha Lefevre

    for (int i = 0; i < length; i += 8) // length = 1176

    -> 1176 / 8 = 147 loop executions

    SqlCeExtentions.ZakdataDatabase_Update(column, valueString, opdrString); // 87ms

    -> 147 * 87ms = 12.8 seconds

    the code snippet below takes 16 seconds

    -> 12.8s * 100% / 16s = 80% The database call makes up for 80% of the time spend for that code. You don't need to optimize the code that you've shown here, you need to optimize the database call. You probably should build a batch statement and use that to update the database only once after the loop is done.

    If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

    OriginalGriffO Offline
    OriginalGriffO Offline
    OriginalGriff
    wrote on last edited by
    #4

    :doh: I missed the "i += 8" - your numbers are right, mine are wrong. But we both think it's the same thing, which is good. You get my upvote and I've edited mine!

    Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...

    "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
    "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

    1 Reply Last reply
    0
    • S Sascha Lefevre

      for (int i = 0; i < length; i += 8) // length = 1176

      -> 1176 / 8 = 147 loop executions

      SqlCeExtentions.ZakdataDatabase_Update(column, valueString, opdrString); // 87ms

      -> 147 * 87ms = 12.8 seconds

      the code snippet below takes 16 seconds

      -> 12.8s * 100% / 16s = 80% The database call makes up for 80% of the time spend for that code. You don't need to optimize the code that you've shown here, you need to optimize the database call. You probably should build a batch statement and use that to update the database only once after the loop is done.

      If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

      G Offline
      G Offline
      GrooverFromHolland
      wrote on last edited by
      #5

      Thank You for your fast response. I should have done the math myself :doh:! Unfortunately there is no bulk-copy for SQL Compact Edition, so the only way I think Is to show the data first in the richTextBox and insert it in the database on a different thread and notify the user when it is successfully finished. Or is there another way? Groover,

      0200 A9 23 0202 8D 01 80 0205 00

      S L 2 Replies Last reply
      0
      • G GrooverFromHolland

        Thank You for your fast response. I should have done the math myself :doh:! Unfortunately there is no bulk-copy for SQL Compact Edition, so the only way I think Is to show the data first in the richTextBox and insert it in the database on a different thread and notify the user when it is successfully finished. Or is there another way? Groover,

        0200 A9 23 0202 8D 01 80 0205 00

        S Offline
        S Offline
        Sascha Lefevre
        wrote on last edited by
        #6

        To be honest, I didn't spend too much thought on the fact that you're using SqlCe. (If you're planning on using this application for several years you might want to consider using a different database because SqlCe is "in deprecation state", meaning that there won't be any new versions and support is running out soon-ish.) I don't really know about the restrictions of SqlCe compared to SQL Server, but Google seems to tell me that SqlCe does not only not support bulk copy but also doesn't support batch statements, which I was originally thinking about. FYI, in "real" database systems you can execute multiple statements at once by sending them as one command-text ("batch"), separated with a semi-colon, e.g. this could be executed with a single command on SQL Server:

        UPDATE myTable SET col1 = @p1 WHERE id = @p2;
        UPDATE myTable SET col1 = @p3 WHERE id = @p4;
        UPDATE myTable SET col1 = @p5 WHERE id = @p6;

        But SqlCe should at least allow you to execute multiple commands (each with one update-statement) within one transaction, which would be the next best solution and should also speed up the process greatly so that you wouldn't have to resort to creating a separate thread for that. I found two projects which might be helpful (though the former suggestion shouldn't be hard to implement): 1) SQL Compact Bulk Insert Library - Home[^] (Apparently only for inserting, not updating) 2) GitHub - lokiworld/Lyare.SqlServerCe.MultiQuery: An extension to the Microsoft SQL Server Compact Edition client library, which simulates the support of the multiple statements in a single command.[^]

        If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

        1 Reply Last reply
        0
        • G GrooverFromHolland

          Thank You for your fast response. I should have done the math myself :doh:! Unfortunately there is no bulk-copy for SQL Compact Edition, so the only way I think Is to show the data first in the richTextBox and insert it in the database on a different thread and notify the user when it is successfully finished. Or is there another way? Groover,

          0200 A9 23 0202 8D 01 80 0205 00

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #7

          I haven't used SQLCE for some time, but the alternative SQLite. SQLite is slow if you update (or insert) in a loop, unless you wrap it in a transaction. I'd also recommend using a List to hold the data, and not a RTF which needs to be redrawn on each modification.

          Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^][](X-Clacks-Overhead: GNU Terry Pratchett)

          1 Reply Last reply
          0
          • G GrooverFromHolland

            Hi all, I know that I write crappy code, but the code snippet below takes 16 seconds on my machine in debug and that is unacceptable. Please help me to speed it up.

            string valueString = string.Empty;
            //List<byte> AtronBytes First 39 bytes = header
            int length = AtronBytes.Count - 39;
            for (int i = 0; i < length; i += 8) // length = 1176
            {
            int colNum;
            if (i == 0) colNum = 1;
            else colNum = i / 8 + 1;
            string column = machineDataColumnNames[colNum];
            //tempAtronBytes = copy of AtronBytes
            byte[] valueByte = tempAtronBytes.GetRange(0, 8).ToArray();
            // last byte of valueByte = checksum
            byte chkVal = Extentions.CalculateOpdrChecksum(tempAtronBytes.GetRange(0, 7).ToArray()); // 1ms
            if (chkVal == tempAtronBytes[7])// checksum test
            {
            valueString = Encoding.ASCII.GetString(
            tempAtronBytes.GetRange(0, 7).ToArray()).Trim();
            // Remove value bytes and checksum:
            tempAtronBytes.RemoveRange(0, 8);

                          SqlCeExtentions.ZakdataDatabase\_Update(column, valueString, opdrString); // 87ms
                          // add to stringBuilder:
                          logAppend(column.PadRight(30), valueString);
                          //Show in richTextbox
                          if (colNum > 146)
                          {
                              logResult();
                          }
                      }
                      else
                      {
                          MessageBox.Show("Checksum error");
                          return;
                      }
                  }
            

            Thanks, Groover

            0200 A9 23 0202 8D 01 80 0205 00

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #8

            You should "count" the number of database inserts / accesses; I think it makes it easier to contemplate the thing. For example, using Entity Framework and SQL Server Express, I can sustain over 1000 table inserts per second while loading entire object graphs.

            G 1 Reply Last reply
            0
            • G GrooverFromHolland

              Hi all, I know that I write crappy code, but the code snippet below takes 16 seconds on my machine in debug and that is unacceptable. Please help me to speed it up.

              string valueString = string.Empty;
              //List<byte> AtronBytes First 39 bytes = header
              int length = AtronBytes.Count - 39;
              for (int i = 0; i < length; i += 8) // length = 1176
              {
              int colNum;
              if (i == 0) colNum = 1;
              else colNum = i / 8 + 1;
              string column = machineDataColumnNames[colNum];
              //tempAtronBytes = copy of AtronBytes
              byte[] valueByte = tempAtronBytes.GetRange(0, 8).ToArray();
              // last byte of valueByte = checksum
              byte chkVal = Extentions.CalculateOpdrChecksum(tempAtronBytes.GetRange(0, 7).ToArray()); // 1ms
              if (chkVal == tempAtronBytes[7])// checksum test
              {
              valueString = Encoding.ASCII.GetString(
              tempAtronBytes.GetRange(0, 7).ToArray()).Trim();
              // Remove value bytes and checksum:
              tempAtronBytes.RemoveRange(0, 8);

                            SqlCeExtentions.ZakdataDatabase\_Update(column, valueString, opdrString); // 87ms
                            // add to stringBuilder:
                            logAppend(column.PadRight(30), valueString);
                            //Show in richTextbox
                            if (colNum > 146)
                            {
                                logResult();
                            }
                        }
                        else
                        {
                            MessageBox.Show("Checksum error");
                            return;
                        }
                    }
              

              Thanks, Groover

              0200 A9 23 0202 8D 01 80 0205 00

              P Offline
              P Offline
              Patrice T
              wrote on last edited by
              #9

              Only a detail replace

                    for (int i = 0; i < length; i += 8) // length = 1176
                    {
                        int colNum;
                        if (i == 0) colNum = 1;
                        else colNum = i / 8 + 1;
              

              with

                    int colNum=0;
                    for (int i = 0; i < length; i += 8) // length = 1176
                    {
                        colNum ++;
              

              It will not really change the overall timing, but should improve a little.

              Patrice “Everything should be made as simple as possible, but no simpler.” Albert Einstein

              G 1 Reply Last reply
              0
              • P Patrice T

                Only a detail replace

                      for (int i = 0; i < length; i += 8) // length = 1176
                      {
                          int colNum;
                          if (i == 0) colNum = 1;
                          else colNum = i / 8 + 1;
                

                with

                      int colNum=0;
                      for (int i = 0; i < length; i += 8) // length = 1176
                      {
                          colNum ++;
                

                It will not really change the overall timing, but should improve a little.

                Patrice “Everything should be made as simple as possible, but no simpler.” Albert Einstein

                G Offline
                G Offline
                GrooverFromHolland
                wrote on last edited by
                #10

                You are absolutely right, I did mention that I write crappy code. :) changed it to:

                int colNum = 0;
                for (int i = 0; i < length; i += 8)
                {
                colNum = i / 8 + 1;

                and zero divided by 8 gives zero, so no need for checking that. :doh: Thanks, Groover

                0200 A9 23 0202 8D 01 80 0205 00

                P 1 Reply Last reply
                0
                • G GrooverFromHolland

                  You are absolutely right, I did mention that I write crappy code. :) changed it to:

                  int colNum = 0;
                  for (int i = 0; i < length; i += 8)
                  {
                  colNum = i / 8 + 1;

                  and zero divided by 8 gives zero, so no need for checking that. :doh: Thanks, Groover

                  0200 A9 23 0202 8D 01 80 0205 00

                  P Offline
                  P Offline
                  Patrice T
                  wrote on last edited by
                  #11

                  Your change correct, but mine is faster.

                  Patrice “Everything should be made as simple as possible, but no simpler.” Albert Einstein

                  1 Reply Last reply
                  0
                  • L Lost User

                    You should "count" the number of database inserts / accesses; I think it makes it easier to contemplate the thing. For example, using Entity Framework and SQL Server Express, I can sustain over 1000 table inserts per second while loading entire object graphs.

                    G Offline
                    G Offline
                    GrooverFromHolland
                    wrote on last edited by
                    #12

                    I followed Your advice and went for SQLite database and entity framework EF6 and the total time needed for the same same code is now 1400 ms vs 16 sec before! It took some time to learn and implement EF(hence the late reply) but it was worth the efford :) Thank You, Groover

                    0200 A9 23 0202 8D 01 80 0205 00

                    L 1 Reply Last reply
                    0
                    • G GrooverFromHolland

                      I followed Your advice and went for SQLite database and entity framework EF6 and the total time needed for the same same code is now 1400 ms vs 16 sec before! It took some time to learn and implement EF(hence the late reply) but it was worth the efford :) Thank You, Groover

                      0200 A9 23 0202 8D 01 80 0205 00

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #13

                      Glad it worked out for you! Didn't mean to say you should use EF; just that more "benchmark numbers" would be useful. But yes; EF lets us think a little less about data access strategies and avoid some mistakes that can cause performance problems. If you haven't already, these were good starting links for EF: Entity Framework (EF) Documentation[^]

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups