🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #17738

Re: Screen

#17738
From: Early Ehlinger
Date: Tue, 04 Mar 2003 14:43
85 lines
5362 bytes
"Mockvichev Nikolai" <mnv@papillon.ru> wrote in message
news:1046752275.599401@fionika.papillon.ru.N.O.S.P.A.M...
> We found that TMemStream.Read(...) equally 2 times slowly than memcpy(...)

This brings up an interesting point...

I haven't profiled it, but from looking at the source of TMemoryStream, it
looks like every time Write(...) is called, there is a potential for the
Capacity property to be increased to precisely enough space to hold the
information that's about to be written.

In other words, the memory potentially gets reallocated on every Write.
Most std::vector implementations, by contrast, will double the capacity of
the vector when you do a push_back rather than merely allocate an additional
/sizeof(value_type)/ bytes.  This is because allocation is typically
*extremely* expensive, and is even more expensive when that memory needs to
be initialized via a copy from an old memory location and followed by a
release of the old buffer.  The net effect is to amortize the cost of
allocation and yield a push_back that takes (amortized) constant time.
Constant time can still be a long time, of course - write a simple loop that
does push_back on a std::vector<DWORD> a thousand times and you'll see what
I mean.

In both TMemoryStream and std::vector, the speed problem isn't the copying
of information into the container, it's the side effect of resizing the
container to accomodate the new data.  A common way to prevent these
problems is to preallocate.  For example, if you are about to do a bunch of
push_backs on std::vector, you would call std::vector::reserve( /n/ ), where
/n/ is a reasonable estimate (or exact value if known) of the number of
elements in the vector *after* the series of push_backs occurs.

With TMemoryStream, you would simply assign a new value to the Capacity
property immediately after construction, thereby preallocating the space you
need.  You can't know the size needed, since JPEG is a rather unpredictable
algorithm in that regard, but you can make a reasonable guess and if you're
capturing the screen repeatedly, you could even track the maximum size
required.

There's only one problem... Capacity is a protected member of TMemoryStream.
So you need to derive from TMemoryStream and expose Capacity:

class TMemoryStreamWithCapacity
  : public TMemoryStream
  {
  public:
    TMemoryStreamWithCapacity
      ( long InitialCapacity = 0 )
      : TMemoryStream( )
      { Capacity = InitialCapacity; }

    __property Capacity; /* expose Capacity property */
  };

Then, in your function:

  static long MaxCap = 0x100000; // 1 Megabyte
    /* Generally I dislike static variables (or
       any variables that have global lifetime),
       but the point here is to show that the
       value is somehow retained between screen
       captures. */

  std::auto_ptr< TMemoryStreamWithCapacity > ms
    ( new TMemoryStreamWithCapacity( MaxCap ) );
    /* Create a TMemoryStreamWithCapacity object,
       tell it to preallocate MaxCap bytes of
       memory. */

  /* Capture Screan, etc... */

  jpg->SaveToStream( ms.get() );
    /* Hopefully TMemoryStreamWithCapacity is
       faster than TMemoryStream since we've
       preallocated :) */

  MaxCap = std::max( ms->Size , MaxCap );
    /* bump up MaxCap if necessary */

--
-- Early Ehlinger CEO, ResPower Inc - Toll-Free : 866-737-7697 --
- RenderFarm - Lightwave , 3dSMax , Bryce , Maya , AfterEffects -
--- www.respower.com -- 500+ GHz Starting At USD$0.50/GHz*Hour --
----------------- SuperComputing For the Masses! ----------------
"I'm so busy programming my computer to let me be lazy, I never
get any rest!" - John Kaster
Technical Details
Message-ID: <3e64bb8d@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!newsfeed.news2me.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mail
References: <3e54df1e$1@newsgroups.borland.com> <3e54e70b@newsgroups.borland.com> <3e54ef6e@newsgroups.borland.com> <3e54f156@newsgroups.borland.com> <3e54fa6f@newsgroups.borland.com> <3e550095$1@newsgroups.borland.com> <3e557074$1@newsgroups.borland.com> <MPG.18bfe0b08613f83a98970a@newsgroups.borland.com> <3e55e0f0@newsgroups.borland.com> <MPG.18c006adda2fd07998970d@newsgroups.borland.com> <3e55ee44$1@newsgroups.borland.com> <MPG.18c021c54fabdd0898970f@newsgroups.borland.com> <3e5971c3$1@newsgroups.borland.com> <3e5b844a$1@newsgroups.borland.com> <3e5b96cc@newsgroups.borland.com> <3e5fd2f1$1@newsgroups.borland.com> <3e62a8b2$1@newsgroups.borland.com> <3e62af4f@newsgroups.borland.com> <3e62b0fb@newsgroups.borland.com> <1046752275.599401@fionika.papillon.ru.N.O.S.P.A.M>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10cc67,9afd9565ba185f43
X-Google-Attributes: gid10cc67,public
X-Google-ArrivalTime: 2003-03-04 13:24:06 PST
From: "Early Ehlinger" <early@respower.com>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <3e54df1e$1@newsgroups.borland.com> <3e54e70b@newsgroups.borland.com> <3e54ef6e@newsgroups.borland.com> <3e54f156@newsgroups.borland.com> <3e54fa6f@newsgroups.borland.com> <3e550095$1@newsgroups.borland.com> <3e557074$1@newsgroups.borland.com> <MPG.18bfe0b08613f83a98970a@newsgroups.borland.com> <3e55e0f0@newsgroups.borland.com> <MPG.18c006adda2fd07998970d@newsgroups.borland.com> <3e55ee44$1@newsgroups.borland.com> <MPG.18c021c54fabdd0898970f@newsgroups.borland.com> <3e5971c3$1@newsgroups.borland.com> <3e5b844a$1@newsgroups.borland.com> <3e5b96cc@newsgroups.borland.com> <3e5fd2f1$1@newsgroups.borland.com> <3e62a8b2$1@newsgroups.borland.com> <3e62af4f@newsgroups.borland.com> <3e62b0fb@newsgroups.borland.com> <1046752275.599401@fionika.papillon.ru.N.O.S.P.A.M>
Subject: Re: Screen
Date: Tue, 4 Mar 2003 08:43:28 -0600
Lines: 89
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
NNTP-Posting-Host: 206.166.224.226
Message-ID: <3e64bb8d@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1046789005 206.166.224.226 (4 Mar 2003 06:43:25 -0800)
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!newsfeed.news2me.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mail