![](https://mail.google.com/mail/images/cleardot.gif)
Dear Dr
Bjarne:
I'm a student from China. And I have some new ideas about some usual problems, which I want to share with you.
I have to apologize for my poor English and some grammar errors which may existing in my following contents.
The attachment is the source code, can be directly compiled and run in all the compiler and system I own.
Begin:
string str = str1 + str2 + str3 + str4;
str = str1 + str2 + str3 + str4 + str;
Large number of temp objects are constructed and destructed in the expressions above, isn't it? Oh no, I can not afford it.
Using "+="? Good idea but bad style, in my opinion.
When binary operator are used in the expression-list like above, it's a grammar tree, in fact. But under control of complier, it generates "fruit" every "season". The temp fruits cost us a lot. Why not generate the final
fruit when "=", in another word, when needed ?
I've designed two methods, like following:
str =
seed<string>() + str1 + str2 + str3 + str4 + str;
or
str =
seeder(str1
) + str2 + str3 + str4 + str;
//The source and test codes are in the attachment.
Brief introduction:
It's very quick, and only
1 temp object generates when operator "=". The "
seed" is used to build the tree all by ourselves and stop the tree
fruit ! When the final fruit is needed, "+=" operator is used to faster the process.
It's helped by
expression-template theory, but not only.
What I focus on is the
interface.
It's non-invasive,easy to use, isn't it? I think it's very important in most projects in industry.
I'd prefer the 2nd way, but my friends remind me that some projects' codes in fact are generated by
macros, so the 1st method comes as addition. The 1st method just need correction at the beginning, so it's easier to used with some complicated macros.
It's generic-type, and does not need c++ 0x support (For portable reason and potential complier's bug, c++ 0x grammar is not allowed to used in most projects).
Because template can not be used for "generic-operator", I just provide operator "+". The interface can be used with some other binary operator if some proper template functions overload are implement and
meet some other
Restrain.
Restrain: Here I use
string and operator "+" as an example to describe the restrain of the type when we want to use the method above on the type. There are two types of
restrain:
grammar
restrain and
semantics restrain
The type
string must :
1. Having constructor with no argument. (
grammar
restrain)
2. Having constructor with
string argument. (
grammar
restrain)
3. Having "+=" operator with the same argument of all the related "+" operator overload. And the return type of operator "+" must be
string. (
grammar
restrain)
(eg.
string& string::operator+= ( const string& str ); string operator+ (const string& lhs, const string& rhs);
string& string::operator+= ( const char* s ); string operator+ (const char* lhs, const string& rhs);
string& string::operator+= ( char c ); string operator+ (char lhs, const string& rhs);
)
4. str = str1
is
equivalent to (str = (string() += str1) ) (
semantics restrain)
5. str1 = str1 + str2
is
equivalent to str1 += str2 (
semantics restrain)
6. str1 + str2 + str3 + ...
is
equivalent to str1 + (str2 + str3 + ...) , it's not needed if you do not want to accelerate the process between the last "( )". (
semantics restrain)
"
equivalent to"
here does not means operator "==". Operator "==" is not needed.
Compiling error comes if
grammar
restrain is not meet, while
semantics restrain error may lead to both compiling error and
run-time error!
Well down!
Test
The following codes are for test. It has tested all I can imagine. The codes can be found in the attachment. The macro TEST_TIME in line 6 can be changed if the test runs too fast :
string str1 = "1234567890";
string str2 = "12345678901234567890";
string str3 = "123456789012345678901234567890";
//raw:
str = "12345678901234567890" + str2 + string("123456789012345678901234567890") + str1 + str2 + str3 + (str1 + str2 + ' '+ (str +=' ') ) ;
//optimized:
str = seed<string>( ) + "12345678901234567890" + str2 + string("123456789012345678901234567890") + str1 + str2 + str3 +
(seed<string>( ) + str1 + str2 + ' '+ (str +=' ')
) ;
str = "12345678901234567890" + any_seeder(str2) + string("123456789012345678901234567890") + str1 + str2 + str3 +
(any_seeder(str1) + str2 + ' ' + (str +=' ')
) ;
// One other seed is needed in the last "( )", or else the expression in the "( )" can not be optimized. It's because the sub-tree is planted before the main branch so the first seed can not affect its growth!
//Seed needs to know the "fruit" type to help the tree to generate implicit-cast function, so the template function "any_seeder" must wrap on object of final result type , like above.
result:
In my windows PC, 40% time reduce can be found on MSVC 6 compiler. Intel compiler v11 will increase the number high up to 60%.
In public Linux or Unix server, TEST_TIME has to be 10 times or more because the server is too fast. And the advantage is not obvious while the reduced time is less than 20%. I think it's because the main costs come from the huge times of memory require and release, and memory fragment increased soon. So the advantage is not as obvious as the test on PC.
The difference between the two method is less than 1% in all systems.
Conclusion
It's effective, light-weighted,
non-invasive, portable(In the attachment codes
, I've try my best on MSVC 6 compiler
) and easy to use, with the only weakness of potential
run-time error if semantics need is not meet
. What's more, I need your opinion and advice. If better method existed, I need your share. If others have invented it before me, thank you for telling me.
Thank you for sparing your time.
附件的代码见下: