Category Archives: Programming

Optimizing C++ code (Visual C++ Team blog)

The Visual C++ Team blog has started a series on Optimizing C++ code.

  1. Introduction
  2. Overview
  3. Constant Folding
  4. Dead Code Elimination

Leave a comment

Filed under C++, Programming

Universal memorisation for C++

ISOCpp linked to a StackOverflow question about universal memorisation.

Leave a comment

Filed under C++, Programming

XPerf Trace Viewer

Bruce Dawson wrote a review of xperf and Windows Performance Analyzer.

Leave a comment

Filed under Programming

Why Mobile Web Apps are so Slow, Drew Crawford

Excellent article that covers lots of reasons why mobile web apps aren’t going to get faster anytime soon. Herb Sutter’s blog post lists some of the contents and a summary.

As a C++ guy, I appreciated the points about garbage collection. I like to be in control of the memory used by my software, and it’s good to know there are sound arguments why explicit memory management is superior in low memory environments:

In particular, when garbage collection has five times as much memory as required, its runtime performance matches or slightly exceeds that of explicit memory management. However, garbage collection’s performance degrades substantially when it must use smaller heaps. With three times as much memory, it runs 17% slower on average, and with twice as much memory, it runs 70% slower. Garbage collection also is more susceptible to paging when physical memory is scarce.

When JavaScript people or Ruby people or Python people hear “garbage collector”, they understand it to mean “silver bullet garbage collector.” They mean “garbage collector that frees me from thinking about managing memory.” But there’s no silver bullet on mobile devices. Everybody thinks about memory on mobile, whether they have a garbage collector or not. The only way to get “silver bullet” memory management is the same way we do it on the desktop–by having 10x more memory than your program really needs.

Leave a comment

Filed under Programming

Windows Timer Resolution

RandomAscii posted an article on Windows Timer Resolution. He reckons that increasing the timer frequency affects energy efficiency and can take a performance hit.

Leave a comment

Filed under Programming

New Concepts Lite paper (2nd revision)

The ISOCpp blogposted a link to the latest Concepts Lite paper.

Leave a comment

Filed under C++, Programming

Runtime-sized arrays v std::dynarray in C++ 14

Interesting question on StackOverflow regarding the differences between the proposals in C++14 for std::dynarray and runtime-sized arrays.

Leave a comment

Filed under C++, Programming

How to serialize a COM object as a Base64 byte array

A component I’m working on needs to be able to serialize its data via JSON.  That’s fine for scalars, arrays and maps, but we also needed to be able to serialize COM objects (there’s a large legacy codebase underneath, much of which is deployed via COM).  It turns out ATL provides API functions for Base 64 encoding (which was a surprise to me and a number of my colleagues).  Here’s some code to make calling it easier (I’ve replaced the production code error handling with simple strings):

std::string to_base_64(int byte_length, const void* bytes  )
{
  if (bytes == 0)
    throw "ToBase64 called with zero bytes";
  
  ATL::CStringA base64;
  int base64_length = ATL::Base64EncodeGetRequiredLength(byte_length);

  if(!ATL::Base64Encode(static_cast<const BYTE*>(bytes), 
                        byte_length, 
                        base64.GetBufferSetLength(base64_length), 
                        &base64_length))
    throw "ATL::Base64Encode failed";

  base64.ReleaseBufferSetLength(base64_length);
  return static_cast<const char*>(CT2A(base64));
}

std::pair<size_t,std::unique_ptr<BYTE>> from_base_64( const std::string& encoded )
{
  // Predict length needed for decoding
  int decoded_length = Base64DecodeGetRequiredLength( encoded.size() );
  std::unique_ptr<BYTE> buffer( new BYTE[decoded_length] );

  // Actual decoded-length may be different to that predicted - method overwrites the value
  if (!Base64Decode(encoded.c_str(), encoded.size(), buffer.get(), &decoded_length))
  {
    throw "ATL::Base64Decode failed";
  }

  return std::make_pair( decoded_length, std::move(buffer) );
}

That leaves the requirement to turn a serializable COM object into a byte array.  The following code does the job provided the COM object implements IPersistStream:

std::pair<size_t, std::unique_ptr<BYTE>> object_to_bytes( IUnknown* pUnk )
{
  // Create an in-memory stream, HGlobalMem will be allocated internally
  HRESULT hr;
  CComPtr<IStream> pIStream;

  if (FAILED(hr = CreateStreamOnHGlobal(0, TRUE, &pIStream)))
    throw "Could not CreateStreamOnHGlobal";

  CComPtr<IPersistStream> pPersistStream;
  if (FAILED(hr = pUnk->QueryInterface(IID_IPersistStream, &pPersistStream ) )
    throw "Failed to QI to IPersistStream";

  CLSID clsid;
  if (FAILED(hr = pPersistStream->GetClassID(&clsid) )
    throw "Failed to get clsid";

  // Serialise CLSID into stream
  if (FAILED(hr = WriteClassStm( pIStream, clsid )))
    throw "WriteClassStm failed";

  // Serialise object into stream
  if (FAILED(hr = pPersistStream->Save( pIStream, TRUE ) )
    throw "Save object into IPersistStream failed";

  // Find out how big the stream is
  LARGE_INTEGER liStart = {0};
  if (FAILED(hr = pIStream->Seek( liStart, STREAM_SEEK_SET, NULL ) )
    throw "IPersistStream::Seek failed";

  STATSTG statstg;
  memset( &statstg, 0, sizeof(statstg) );

  if (FAILED(hr = pIStream->Stat( &statstg, STATFLAG_NONAME ) )
    throw "IPersistStream::Stat failed";

  // Populate a byte array from the stream
  std::unique_ptr<BYTE> buffer( new BYTE[statstg.cbSize.LowPart] );
  unsigned long size_read;
  if (FAILED(hr = pIStream->Read( (void*)buffer.get(), statstg.cbSize.LowPart, &size_read ) )
    throw "IPersistStream::Read failed";

  ASSERT( size_read == statstg.cbSize.LowPart );

  return std::make_pair( size_read, std::move(buffer) );
}

CComPtr<IUnknown> bytes_to_object( size_t length, void* bytes )
{
  HRESULT hr;
  CComPtr<IStream> pIStream;

  HGLOBAL handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_NODISCARD, length );

  if (FAILED(hr = CreateStreamOnHGlobal(handle, TRUE, &pIStream)))
    throw "Could not CreateStreamOnHGlobal";

  unsigned long size_written;
  if (FAILED(hr = pIStream->Write( bytes, length, &size_written ) )
    throw "Failed to write to stream";

  // Reset the stream
  LARGE_INTEGER liStart = {0};

  if (FAILED(hr = pIStream->Seek( liStart, STREAM_SEEK_SET, NULL ) )
    throw "IPersistStream::Seek failed";

  // Serialise CLSID out of stream
  CLSID clsid;

  if (FAILED(hr = ReadClassStm( pIStream, &clsid )))
    throw "ReadClassStm failed";

  // Create object from the clsid and stream from IStream into the object, using IPersistStream
  CComPtr<IUnknown> pUnk;
  if (FAILED(hr = ::CoCreateInstance(clsid, NULL, CLSCTX_ALL, &pUnk ) )
    throw "Failed to CoCreate clsid";

  CComPtr<IPersistStream> pStream;
  if (FAILED(hr = pUnk->QueryInterface(IID_IPersistStream, &pStream ) )
    throw "Failed to QI to IPersistStream";

  if (FAILED(hr = pStream->Load( pIStream ) )
    throw "IPersistStream::Load failed";

  return pUnk;
}

Then it’s a matter of putting the methods together to achieve a simple API:

std::string to_base64_encoded_byte_array( IUnknown* pUnk )
{
  auto bytes = object_to_bytes( pUnk );
  return to_base_64( bytes.first, bytes.second.get() );
}

CComPtr<IUnknown> from_base64_encoded_byte_array( const std::string& encoded)
{
  auto bytes = from_base_64( encoded );
  return bytes_to_object( bytes.first, bytes.second.get() );
}

Leave a comment

Filed under C++, C++ Code, Programming

How to downcast a shared_ptr

A lot of the codebase I work on is deployed as COM servers. This means that it isn’t uncommon to pass an array of objects as an of pointers to base (i.e. IUnknown) and then downcast to the specific interface you want using QueryInterface.

I found myself in a similar situation with some more modern C++, where I had a std::vector<std::shared_ptr> and wanted to convert each pointer to a shared_ptr in order to call into some API method. The question is – if you have a std::shared_ptr<T1>, how to cast it to a std::shared_ptr<T2>  (for suitably related T1 and T2)?

This question was already asked on StackOverflow and the answers pointed me at std::dynamic_pointer_cast and std::static_pointer_cast, which are analogous to static_cast/dynamic_cast for raw pointers.

class B
{
public:
  virtual void Print(){ std::cout << "Object type B\n"; }
  virtual ~B(){};
};

class C : public B
{
public:
  virtual void Print(){ std::cout << "Object type C\n"; }
  void BehaveLikeC()  {std::cout << "Behave like C\n";}
};

class D : public B
{
public:
  virtual void Print(){ std::cout << "Object type D\n"; }
  void BehaveLikeD() { std::cout << "Behave like D\n"; }
};

void DoSomething( const std::shared_ptr<D>& d )
{
    d->BehaveLikeD();
}

int _tmain(int argc, _TCHAR* argv[])
{
  std::vector<std::shared_ptr<b>> elements;
  elements.push_back( std::make_shared<C>() );
  elements.push_back( std::make_shared<D>() );

  // Call base class method on all elements
  std::for_each( elements.begin(), elements.end(),
    []( const std::shared_ptr<b>& b ){ b->Print(); });

  // Call C behaviour on all C elements
  for ( size_t i = 0; i < elements.size(); ++i )
  {
    auto c = std::dynamic_pointer_cast( elements[i] );
    if (c ){ c->BehaveLikeC(); }

    auto d = std::dynamic_pointer_cast<D>( elements[i] );
    if (d){ DoSomething(d); }
  }

  return 0;
}

1 Comment

Filed under C++, C++ Code, Programming

Morgan Stanley HFT Overhaul

TheTradeNews.com reports that Morgan Stanley’s HFT software re-write is promising:

“This is the first time we’ve done a full re-write of our equity trading infrastructure – it’s brand new software running on brand new hardware, and we’ve specifically brought in expertise from low latency trading firms to achieve this”

Leave a comment

Filed under Finance, Programming