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. Compute Speed of Download Algorithm

Compute Speed of Download Algorithm

Scheduled Pinned Locked Moved C#
questioncsharpalgorithmsperformanceannouncement
15 Posts 4 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.
  • Z zx2c4

    Currently, I am working on ZX2C4 Instant Messenger. ( http://zx2c4-im.sf.net ). For file transfers, a connection class raises an event for every 1024 bytes it receives (and finally length%1024 bytes at the end). This event is picked up by a form that has a progress bar. Everytime the event is called, I make the progress bar's value maximumvalue * (bytes trasfered/total). However, I lack a good way to compute the number of kb/s at which the file is downloading. Currently, when the progress bar is created, I assign a global varible called "start" to DateTime.Now, and every time the update event is signaled, I make the current speed equal to (bytes transfered) / (DateTime.Now - start). While this works, it only provides the average speed of the whole download. What is the best way to calculate the current speed of the download? Jason A. Donenfeld ZX2C4 Instant Messenger

    R Offline
    R Offline
    Ravi Bhavnani
    wrote on last edited by
    #2

    zx2c4 wrote:

    What is the best way to calculate the current speed of the download?

    Since the event is conveniently raised after every 1KB is downloaded, I believe this is simply the 1/(ti - ti - 1) where "t" is the wall clock time. /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com

    Z 1 Reply Last reply
    0
    • R Ravi Bhavnani

      zx2c4 wrote:

      What is the best way to calculate the current speed of the download?

      Since the event is conveniently raised after every 1KB is downloaded, I believe this is simply the 1/(ti - ti - 1) where "t" is the wall clock time. /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com

      Z Offline
      Z Offline
      zx2c4
      wrote on last edited by
      #3

      Right. That's what I'm doing. But how do I make it not the average rate, but the present rate instead?

      R 1 Reply Last reply
      0
      • Z zx2c4

        Right. That's what I'm doing. But how do I make it not the average rate, but the present rate instead?

        R Offline
        R Offline
        Ravi Bhavnani
        wrote on last edited by
        #4

        Oh, that's even easier! Just keep track of the total # bytes downloaded and the total elapsed time and divide the 2. :) [edit] Wait, my previous post gives you the present download rate. If you want the average download rate, see the current post. [/edit] /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com -- modified at 18:54 Wednesday 3rd May, 2006

        Z 1 Reply Last reply
        0
        • R Ravi Bhavnani

          Oh, that's even easier! Just keep track of the total # bytes downloaded and the total elapsed time and divide the 2. :) [edit] Wait, my previous post gives you the present download rate. If you want the average download rate, see the current post. [/edit] /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com -- modified at 18:54 Wednesday 3rd May, 2006

          Z Offline
          Z Offline
          zx2c4
          wrote on last edited by
          #5

          Nono you miss read -- that does the average rate. I want the present rate. Doing 1/(difference between time now and time of last event) will produce sporatic behavior -- the number jumps around tons and tells nothign to the user. Is the only way to do this to just do 1*n / (difference between now and time of n events ago) ?

          R 1 Reply Last reply
          0
          • Z zx2c4

            Currently, I am working on ZX2C4 Instant Messenger. ( http://zx2c4-im.sf.net ). For file transfers, a connection class raises an event for every 1024 bytes it receives (and finally length%1024 bytes at the end). This event is picked up by a form that has a progress bar. Everytime the event is called, I make the progress bar's value maximumvalue * (bytes trasfered/total). However, I lack a good way to compute the number of kb/s at which the file is downloading. Currently, when the progress bar is created, I assign a global varible called "start" to DateTime.Now, and every time the update event is signaled, I make the current speed equal to (bytes transfered) / (DateTime.Now - start). While this works, it only provides the average speed of the whole download. What is the best way to calculate the current speed of the download? Jason A. Donenfeld ZX2C4 Instant Messenger

            G Offline
            G Offline
            Guffa
            wrote on last edited by
            #6

            Keep the time for the last few blocks, and calculate the average speed for them. That way you get a more accurate speed than just calculating the speed of the last block. --- b { font-weight: normal; }

            Z 1 Reply Last reply
            0
            • G Guffa

              Keep the time for the last few blocks, and calculate the average speed for them. That way you get a more accurate speed than just calculating the speed of the last block. --- b { font-weight: normal; }

              Z Offline
              Z Offline
              zx2c4
              wrote on last edited by
              #7

              Is there any other way than grouping a block of events together?

              G P 2 Replies Last reply
              0
              • Z zx2c4

                Nono you miss read -- that does the average rate. I want the present rate. Doing 1/(difference between time now and time of last event) will produce sporatic behavior -- the number jumps around tons and tells nothign to the user. Is the only way to do this to just do 1*n / (difference between now and time of n events ago) ?

                R Offline
                R Offline
                Ravi Bhavnani
                wrote on last edited by
                #8

                zx2c4 wrote:

                Doing 1/(difference between time now and time of last event) will produce sporatic behavior

                Yes, it will if the download rate isn't constant. The average rate (average of all "present" rates) is nothing but the total # bytes downloaded divided by the time taken to download them. [edit] You could take Guffa's approach and calculate the average of the last "n" chunks. [/edit] /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com -- modified at 19:03 Wednesday 3rd May, 2006

                Z 1 Reply Last reply
                0
                • R Ravi Bhavnani

                  zx2c4 wrote:

                  Doing 1/(difference between time now and time of last event) will produce sporatic behavior

                  Yes, it will if the download rate isn't constant. The average rate (average of all "present" rates) is nothing but the total # bytes downloaded divided by the time taken to download them. [edit] You could take Guffa's approach and calculate the average of the last "n" chunks. [/edit] /ravi My new year's resolution: 2048 x 1536 Home | Music | Articles | Freeware | Trips ravib(at)ravib(dot)com -- modified at 19:03 Wednesday 3rd May, 2006

                  Z Offline
                  Z Offline
                  zx2c4
                  wrote on last edited by
                  #9

                  I've tried it and the behavior is sporatic -- the time interval is too small.

                  1 Reply Last reply
                  0
                  • Z zx2c4

                    Is there any other way than grouping a block of events together?

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

                    What do you mean? --- b { font-weight: normal; }

                    1 Reply Last reply
                    0
                    • Z zx2c4

                      Is there any other way than grouping a block of events together?

                      P Offline
                      P Offline
                      Phil C
                      wrote on last edited by
                      #11

                      well yes there is, but you said you didn't like it when you didn't group because the time frame was to0 small the the results were too erratic You only have three choices here: 1) display the total average transfer rate (which u already do). 2) display the rate at which the last 1k block came in (which you don't like) 3) group up 2, or 3, or 4 or 5 1k blocks and display a moving average Those are your choices...pick one. FWIW, you can do a fairly clean moving average by creating a variable for the total time it's taken for the last n number of blocks. Every time a new block comes in, figure out how much time went by, subtract the old average rate (sumx/n) then add the new amount of time and then display to the user the new sumx/n value. Note that the first time you subtract sumx will still be 0, so subtracting sumx -= sumx/n will still equal 0; This has the effect of the "download speed" starting out kind of slow then picking up until you reach n blocks, then it will be displaying the average of the last n blocks from there on out. You also don't really have to "group" anything or re-organize your downloads, just add one variable and do a little math. I've used that method for years to display moving averages and all kinds of other statistics (add a sumx^2 and a different equation to get standard deviations), about the only thing you have to watch out for is that your sumx doesn't overflow, but with todays 32bit integers and the numbers you're talking about that won't likely be an issue. It beats the heck out of having to allocate arrays or remember each individual download timeslice. Just one variable and a little math.

                      Z 1 Reply Last reply
                      0
                      • P Phil C

                        well yes there is, but you said you didn't like it when you didn't group because the time frame was to0 small the the results were too erratic You only have three choices here: 1) display the total average transfer rate (which u already do). 2) display the rate at which the last 1k block came in (which you don't like) 3) group up 2, or 3, or 4 or 5 1k blocks and display a moving average Those are your choices...pick one. FWIW, you can do a fairly clean moving average by creating a variable for the total time it's taken for the last n number of blocks. Every time a new block comes in, figure out how much time went by, subtract the old average rate (sumx/n) then add the new amount of time and then display to the user the new sumx/n value. Note that the first time you subtract sumx will still be 0, so subtracting sumx -= sumx/n will still equal 0; This has the effect of the "download speed" starting out kind of slow then picking up until you reach n blocks, then it will be displaying the average of the last n blocks from there on out. You also don't really have to "group" anything or re-organize your downloads, just add one variable and do a little math. I've used that method for years to display moving averages and all kinds of other statistics (add a sumx^2 and a different equation to get standard deviations), about the only thing you have to watch out for is that your sumx doesn't overflow, but with todays 32bit integers and the numbers you're talking about that won't likely be an issue. It beats the heck out of having to allocate arrays or remember each individual download timeslice. Just one variable and a little math.

                        Z Offline
                        Z Offline
                        zx2c4
                        wrote on last edited by
                        #12

                        This is exactly the sort of solution I'm looking for. However, I still do not understand completely the math involved. Can you write some psudo-code to help demonstrate this idea?

                        P 1 Reply Last reply
                        0
                        • Z zx2c4

                          This is exactly the sort of solution I'm looking for. However, I still do not understand completely the math involved. Can you write some psudo-code to help demonstrate this idea?

                          P Offline
                          P Offline
                          Phil C
                          wrote on last edited by
                          #13

                          well now, I'm not going to do the whole thing for you. I don't know how you have it set up so it's a bit tough for me to guess. but assuming you have a function that gets called every time a 1k chunk is downloaded I'd do it this way: Forgive the lack of indenting, I never have figured out how to put tabs in these messages, I hit the tab key and my cursor jumps to the next block in the web page. I used spaces, but they don't make it either. startdownload() { m_sumx = 0;//running sum of the moving average..initialize it m_numsamps = 3;//change to adjust sample size, otherwise just a fixed value } new1kblock()//this function gets called every time a 1k block arrives { int elapsedtime = whateveryouuse();//pretend it's in seconds, //I don't know what units you're dealing with, converting is up to you //m_sumx holds the sum of the last 3 values, first subtract 1/3 to keep // it from growing to infinity m_sumx -= m_sumx/m_numsamps; //then add the latest elapsed time m_sumx += elapsedtime; //ok, now sumx is again the sum of the last three values float dlspeed=0; if(m_sumx>0)//be careful to avoid divide by zero, it can happen dlspeed = 1024.0/(float)m_sumx/(float)m_numsamps; //in this example dlspeed is now a value representing how fast we // downloaded the last 3 1k chunks in bits/second. // Display it however you desire }

                          Z 1 Reply Last reply
                          0
                          • P Phil C

                            well now, I'm not going to do the whole thing for you. I don't know how you have it set up so it's a bit tough for me to guess. but assuming you have a function that gets called every time a 1k chunk is downloaded I'd do it this way: Forgive the lack of indenting, I never have figured out how to put tabs in these messages, I hit the tab key and my cursor jumps to the next block in the web page. I used spaces, but they don't make it either. startdownload() { m_sumx = 0;//running sum of the moving average..initialize it m_numsamps = 3;//change to adjust sample size, otherwise just a fixed value } new1kblock()//this function gets called every time a 1k block arrives { int elapsedtime = whateveryouuse();//pretend it's in seconds, //I don't know what units you're dealing with, converting is up to you //m_sumx holds the sum of the last 3 values, first subtract 1/3 to keep // it from growing to infinity m_sumx -= m_sumx/m_numsamps; //then add the latest elapsed time m_sumx += elapsedtime; //ok, now sumx is again the sum of the last three values float dlspeed=0; if(m_sumx>0)//be careful to avoid divide by zero, it can happen dlspeed = 1024.0/(float)m_sumx/(float)m_numsamps; //in this example dlspeed is now a value representing how fast we // downloaded the last 3 1k chunks in bits/second. // Display it however you desire }

                            Z Offline
                            Z Offline
                            zx2c4
                            wrote on last edited by
                            #14

                            Thank you so much! The download speed seems much more sporatic though :'(. Here's my implementation: public void UpdateStatus(double percentage) { this.progressBar1.Value = (int)Math.Round(((double)this.progressBar1.Maximum * percentage)); this.label2.Text = String.Format("Progress: {0}%", Math.Round(percentage * 100.0, 2)); _movingAverage -= _movingAverage / (double)SAMPLESIZE; _movingAverage += (DateTime.Now - _lastSegment).TotalSeconds; _lastSegment = DateTime.Now; if (_movingAverage > 0) { this.label1.Text = String.Format("Speed: {0} kb/s", Math.Round(((double)SAMPLESIZE * (double)StreamUtils.FilePacketSize / 1024.0) / _movingAverage, 2)); } else { this.label1.Text = "Speed: N/A"; } } The download speed is strangly sporatic though...

                            P 1 Reply Last reply
                            0
                            • Z zx2c4

                              Thank you so much! The download speed seems much more sporatic though :'(. Here's my implementation: public void UpdateStatus(double percentage) { this.progressBar1.Value = (int)Math.Round(((double)this.progressBar1.Maximum * percentage)); this.label2.Text = String.Format("Progress: {0}%", Math.Round(percentage * 100.0, 2)); _movingAverage -= _movingAverage / (double)SAMPLESIZE; _movingAverage += (DateTime.Now - _lastSegment).TotalSeconds; _lastSegment = DateTime.Now; if (_movingAverage > 0) { this.label1.Text = String.Format("Speed: {0} kb/s", Math.Round(((double)SAMPLESIZE * (double)StreamUtils.FilePacketSize / 1024.0) / _movingAverage, 2)); } else { this.label1.Text = "Speed: N/A"; } } The download speed is strangly sporatic though...

                              P Offline
                              P Offline
                              Phil C
                              wrote on last edited by
                              #15

                              maybe things are happening faster than you think. Put a temporary label1.Text = String.Format("_movingAverage={0}", _movingAverage) statement to see what kind of values you are working with. ie. is it typically 0, 0, 3, 0, 3, 0, 3? or is it typically 35, 39, 31, 39...? What about adjust the SAMPLESIZE up, that have any effect? Tinker a little and use the debugger you'll get it :)

                              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