Code Optimization

Can the following code be optimized using inline-assembly or in any other way? This portion is in a loop that runs many 10s of thousands of times which causes unacceptable delay. On each loop iteration subRecord is a string of variable size and the idea is to append the new subRecord to sRecord after dynamically re-sizing sRecord. It is obvious that it gets slower as the loop count increases.


//..definition..
//char *subRecord=NULL;
//char *sRecord=NULL;
...
sRecord = (char*)realloc(sRecord,_msize(sRecord) + (sizeof(char)*(strlen(subRecord))));

strcat(sRecord,subRecord);
free(subRecord);
...
arvind_csAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

KangaRooCommented:
use std::vector
0
arvind_csAuthor Commented:
No, KangaRoo, that does not serve my purpose as I want a concatenated string in the form of sRecord (thousands of characters long) to be passed back to another function as char*. If I use template library, I would have to iterate outside the loop to build my sRecord string after using vector.push_back inside the loop.
Any other ideas?

0
imladrisCommented:
Seeing as the code snippet does little besides realloc, which is largely an operating system function, there is little to be done with code optimization perse.
The realloc function can return the same block enlarged or a different one. In the latter case it will have to copy the memory contents across.
Altering the algorithm will probably yield better results that optimization.
How about pulling in all the subrecords and mallocing space for them. Then, when you can tell how much total memory you need, malloc one big block for that and copy all the pieces into it.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

carldeanCommented:
The usual way is to pre-allocate a chunk of memory that you think will be big enough.  You will therefore save on
reallocs and it will be more efficient.

Even if you wrote assembler you'd still have to reallocate at some point - unless your first guess was a good one!
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
KangaRooCommented:
malloc() and free() are expensive, reduce the numebr of calls to them
1) use std::string, or
2a) Expand sRecord in very large chunks, sufficient to contain several subRecords.
2b) Reuse the buffer for subRecord, realloc it if it's too small for a particular case, like sRecord
//====================================================================
// size_t current_size = _msize(sRecord);
// size_t increment = 16 * _msize(subRecord)
// ...

if(strlen(sRecord) + strlen(subRecord) > current_size)
   sRecord = realloc(sRecord, (current_size += increment));
strcat(sRecord,subRecord);
// etc...
0
KangaRooCommented:
With modern OS and plenty of virtual memory you could indeed allocate huge amounts of memory (100++ MB). Given the sequential way in which the code operates, trashing will be minimal, even less then when you're using realloc().
0
gvgCommented:
Here are few ideas.  They might sound stupid but I do not have much to go on like where do the strings come from and so on.

Ok.  You might try to use a second variable that tells you how big of a memory you have allocated and then to start with allocate big chunk.  If this is an option you might get very few realloc.

If you are using MFC you might let CString do allocation for you and keep track of the memory length.  Now when you are done appending you call FreeExtra and now memory is wasted.

I don't where you get subRecord from but if you first copy it into subRecord and then into sRecord you might save some time by resizing first and copying it directly to sRecord by for example making subRecord point to sRecord end.

Hope this helps.

Gunnar Valur


0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.