Link to home
Start Free TrialLog in
Avatar of eNarc
eNarcFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Easy Way of Showing Kb/s

Hi I've like a easy way of being able to show the Kb/s in a function


something like

edit1.text:= IntToStr(DisplayKBS(TimeStart,TimeNow,TotalBytesSoFar))+'kb/s';

Will display = 23kb/s
Avatar of 2266180
2266180
Flag of United States of America image

like this?
uses dateutils;
 
function DisplayKBS(TimeStart,TimeNow:TDateTime; TotalBytesSoFar:integer):integer;
begin
  result:=round(TotalBytesSoFar/SecondsBetween(TimeNow, TimeStart));
end;

Open in new window

Or this :o)
uses DateUtils;
 
function DisplayKBS(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer): Integer;
begin
  Result := Round(TotalBytesSoFar / SecondsBetween(TimeStart, TimeNow) / 1024);
end;

Open in new window

you're right, it's kilo not simple. also, it's KB/s and not kb/s so if enarc really wants kb/s (kilo bits) and not KB/s (kilo bytes) then
uses DateUtils;
 
function DisplayKBS(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer): Integer;
begin
  Result := Round(TotalBytesSoFar / SecondsBetween(TimeStart, TimeNow) / 128);
end;

Open in new window

Why would you want kilobits/sec? If he's asking this question, I doubt he'd need kbits/sec in stead of kbyte/sec. Also the title is "Easy Way of Showing Kb/s" with capital "K".

So, eNarc:
- For KiloBytes / second, divide by 1024
- For Kilobits / second, divide by 128
SOLUTION
Avatar of ahalya
ahalya
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I guess this will be a three-way split :)
Avatar of eNarc

ASKER

Hi, when I try all the functions, I get an error, cants devide by 2 :( and yea in kbs like 50kbs


uses
  DateUtils


//rohypnol
function DisplayKBS1(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer): Integer;
begin
  Result := Round(TotalBytesSoFar / SecondsBetween(TimeStart, TimeNow) / 1024);
end;



//ciuly
function DisplayKBS2(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer): Integer;
begin
  Result := Round(TotalBytesSoFar / SecondsBetween(TimeStart, TimeNow) / 128);
end;



//ahalya
function FormatToKBs2(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer): string;
begin;
  result := Format('%5.1f', [TotalBytesSoFar/SecondsBetween(TimeNow, TimeStart)/1024]); //assuming kB/sec.
end;

procedure TForm1.Button1Click(Sender: TObject);
var StartTime : Int64; FileSize,FileCopied,PacketSize,TotalBytesSoFar : Int64;
TimeStart:TDateTime;
 i:integer;
begin
TimeStart:=Now;
TotalBytesSoFar:=0;
for I := 0 to 1000 do begin

TotalBytesSoFar:=TotalBytesSoFar+1024;

edit1.text:=IntToStr(DisplayKBS1(TimeStart, Now,TotalBytesSoFar));
edit2.text:=IntToStr(DisplayKBS2(TimeStart, Now,TotalBytesSoFar));
edit3.text:=FormatToKBs2(TimeStart, Now,TotalBytesSoFar);
edit4.text:=inttostr(TotalBytesSoFar);
wait(1);
end;
end;



displays...
edit1.text:=91
edit2.text:=728
edit3.text:=91.0
edit4.text:=1025024
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
function FormatToKBs2(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer): string;
begin;
  if (timenow <> timestart) then
    result := Format('%5.1f', [TotalBytesSoFar/SecondsBetween(TimeNow, TimeStart)/1024]);
  else
    result := 0; // unknown, because otherwise it would give infinity. this happens only if showing it very quickly after the transfer starts
end;
I think ciuly's last post is the best way to do this.
Avatar of eNarc

ASKER

After testing them all I've come up to one I like the best.


function kbs(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer): string;
begin;
  result := Format('%.1f', [TotalBytesSoFar/MilliSecondsBetween(TimeNow, TimeStart)]); //assuming kB/sec.
end;

I like this one the best, I've modified the function so it has MilliSecondsBetween, because for the rest I had to sleep the program for a second before it would continue.

here is what I used to execute the function.
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 216
  ClientWidth = 426
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Edit1: TEdit
    Left = 8
    Top = 8
    Width = 121
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
  end
  object Button1: TButton
    Left = 8
    Top = 35
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 1
    OnClick = Button1Click
  end
end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DateUtils, Math, Idhttp, StdCtrls;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function kbs(TimeStart, TimeNow: TDateTime; TotalBytesSoFar: Integer; Layout:String): string;
begin;
  result := Format(Layout, [TotalBytesSoFar/MilliSecondsBetween(TimeNow, TimeStart)]); //assuming kB/sec.
end;
 
function GetUrlData(url : string): AnsiString;
var
  PostDataStream : TStringStream;
  WebPageContent : AnsiString;
  IdHTTP         : TIdHTTP;
begin
  IdHTTP := TIdHTTP.Create(nil);
  IdHTTP.AllowCookies:=true;
  IdHTTP.HandleRedirects:=true;
  IdHTTP.Request.UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.12) Gecko/22454322 Firefox/2.0.0.16';
  try
    PostDataStream := TStringStream.Create('');
    try
      IdHTTP.Get(url, PostDataStream);
      WebPageContent  := PostDataStream.DataString;
    finally
      PostDataStream.Free;
      result := WebPageContent;
    end;
  finally
    IdHTTP.Free;
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var TotalBytes:Int64; TimeStart, TimeFinish:TDateTime; Buffer:string;
begin
  TotalBytes:=0;
  TimeStart:=Now;
    Buffer:=GetUrlData('http://www.experts-exchange.com/');
  TimeFinish:=Now;
  TotalBytes:=Length(Buffer);
  edit1.text:=kbs(TimeStart, TimeFinish, TotalBytes,'%.1f');
end;
 
end.

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of eNarc

ASKER

ooooo I wasn't aware of that, you know, I did wonder about that *rolls eyes* hehe, because it was increasing... bit by bit lol, so thats why it was increasing, thanks for telling that :D
>> because for the rest I had to sleep the program for a second before it would continue.

that's because you used it incorrectly. I have given an idea with using a max function to get over the division by 0 error, and rohypnol gave you another workaround with comparing timestamps. there are other methods as well but they would only be derivates of the same idea: comparing something so that you catch the possible exception in a comparison instead of letting it fly out. you can also use a try except construct but that's kind of ugly.
That was my first idea but then I realized what the side-effects would have been (teaching someone to use exception handling like that). Anyway, I find it impossible to believe how many comments we have for such a simple problem. I hope this teaches everyone a lesson :) It's your decision but I think ciuly's solution should be accepted because it's the simplest and it teaches you a cool and rather dirty hack that you will probably use more often later - probably more often than you should, as we all do, but I'm sure you will.
Avatar of eNarc

ASKER

Hi ciuly, the max sure did help, it took away the need to compare, made it a much simpler code and shorter and faster and your right rohypnol, from such a simple problem so many comments ;) though I have learnt more than I had anticipated :D so I greatly appreciate that :)

this is the function I'm up to at the moment, in the speed test, this function below did it in 6 while the other did it in 23 which was almost 4x as fast as the other.
function kbs(TimeStart, TimeNow: TDateTime; TotalBytes: Integer): string;
begin;
  Result := IntToStr(Round(TotalBytes/ max(1,SecondsBetween(TimeStart, TimeNow)) / 1024));
end;
 
the function for checking the speed I used this
 
 
function Performance(id:int64):Int64;
//var PerformanceBegin,PerformanceEnd:Int64;
begin;
  result := -1;
  case id of
    0:if QueryPerformanceCounter(PerformanceBegin) then Result := PerformanceBegin;
    1:if QueryPerformanceCounter(PerformanceEnd) then Result := PerformanceEnd;
    2:Result := PerformanceEnd - PerformanceBegin;
  end;
end;
 
 
Performance(0);
  o:=kbs(TimeStart, TimeFinish, TotalBytes);
Performance(1);
  edit5.text:=IntToStr(Performance(2));

Open in new window

>> Hi ciuly, the max sure did help, it took away the need to compare

max function compares as well :) it just does it behind the scene ;) so the performance gain is not that much. the speed loss in the otehr functions is given by the format function and not datetime comparison, which is really a real type, basically a number.

PS: I know you have issues with this (I and ziolko cleaned up a lot of your questions) so I remind you to not forget and close this question once everything is settled
Avatar of eNarc

ASKER

Thankyou :)