SSD6中Exercise4 (substitute.cpp) 答案解析
2008-12-01 22:55
162 查看
今天终于把Exercise4搞定了,昨天大约优化了0.38秒,今天优化了0.52秒,跨越了一大步。
在我们未加任何修饰执行此代码时,其执行后所用时间如图(摘抄主要):
我们发现insertChar()函数里面就一条return语句,这完全没必要,何必还调用一个函数呢,申请栈释放栈很浪费时间,然后我们去掉这个函数,直接在别的函数里面用它里面的语句。
我们再来看
for (int i = 0; i < replacement->Length; i++) {
data = insertChar(data, loc+i, replacement, i);
// data->Insert(loc + i, replacement->Substring(i, 1));
}
这个也没必要,何必一个一个的插入呢?整体插入就算了。因而可以改为
return data->Insert(loc,replacement);
对于indeof函数,占的时间实在太多,是该解决一下它,在原函数中间是这样的:
for (loc = data->IndexOf(pattern, 0); loc >= 0;
loc = data->IndexOf(pattern, 0)) {
// replace word
data = replace_word(data, loc, pattern->Length, replacement);
}
没必要总是从第一个找起吧!起先我想的是从上一次查找的结束的下一个位置开始查找,但这样有一个问题。例如我们用dd替换cd,有一个字符串为cccd,第一次替换后为ccdd,不应该只是往后找,因为此时前面也出现了cd,故而在这里我们可以从新得到的loc 前 pattern->length处开始查找,再往前开始找没意义。在这里还就是pattern->Length最好在外面用一个变量代替,如pl,放置循环次次都计算pattern->Length(你可能认为编译器足够聪明,但我们不敢保证它在这里“敢”优化,毕竟pattern是个指针,随时可以变,还是我们替他提早优化,参考《深入理解计算机系统》)。
故而这段程序改为:
int location = 0;
int pl = pattern->Length;
// find every occurrence of pattern:
for (loc = data->IndexOf(pattern, 0); loc >= 0;
loc = data->IndexOf(pattern, location)) {
// replace word
int dis = loc - pl;
if (dis >= 0)
{
location = dis;
}
else
{
location = 0;
}
data = replace_word(data, loc, pl, replacement);
改过的程序为:
#include <iostream>
using namespace std;
using namespace System;
using namespace System::IO;
using namespace System::Text;
//String* insertChar(String *data, int loc, String *replacement, int i) {
// return data->Insert(loc, replacement->Substring(i, 1));
//}
String* replace_word(String* data, int loc, int length, String* replacement) {
// delete the pattern string from loc:
data = data->Remove(loc, length);
// insert each character of the replacement string:
//for (int i = 0; i < replacement->Length; i++) {
// data = insertChar(data, loc+i, replacement, i);
// // data->Insert(loc + i, replacement->Substring(i, 1));
//}
return data->Insert(loc,replacement);
//->Insert(loc,replacement)
}
String* string_subst(String *data, String *pattern, String *replacement) {
try {
int loc;
int location = 0;
int pl = pattern->Length;
// find every occurrence of pattern:
for (loc = data->IndexOf(pattern, 0); loc >= 0;
loc = data->IndexOf(pattern, location)) {
// replace word
int dis = loc - pl;
if (dis >= 0)
{
location = dis;
}
else
{
location = 0;
}
data = replace_word(data, loc, pl, replacement);
}
return data;
} catch (Exception *e) {
Console::WriteLine("Error in substitute ");
Console::WriteLine(e->ToString());
return data;
}
}
String* batch_subst(String *data, const char* subs_filename) {
try {
String *subs_file = new String(subs_filename);
StreamReader *subs_reader = new StreamReader(subs_file);
String *pattern, *replacement, *separator;
while (subs_reader->Peek() >= 0) {
pattern = subs_reader->ReadLine();
replacement = subs_reader->ReadLine();
separator = subs_reader->ReadLine();
data = string_subst(data, pattern, replacement);
}
return data;
} catch(Exception* e ) {
Console::WriteLine( "Error in do_substitutions ");
Console::WriteLine( e->ToString());
return data;
}
}
void process_file(const char* filename, const char* subs_filename) {
StreamReader *reader;
StreamWriter *writer;
String *file = new String(filename);
try {
reader = new StreamReader( file );
String *data = reader->ReadToEnd();
data = batch_subst(data, subs_filename);
reader->Close();
// write the data
writer = new StreamWriter(file, false);
writer->Write(data);
writer->Close();
} catch(Exception* e) {
Console::WriteLine( "Error while processing file ");
Console::WriteLine( e->ToString());
}
}
int main(int argc, char *argv[]) {
if (argc < 3) {
cout << "Not enough input arguments" << endl;
cout << "Usage: substitute subs-file src1 src2 ..." << endl;
} else {
for (int i = 2; i < argc; i++) {
process_file(argv[i], argv[1]);
}
}
return 0;
}
我还准备优化那个reader->Close();writer->Close();没必要每次都关闭。但尝试了一下,最终失败。希望看过此文章的人不吝赐教,多多指导,共同学习。
在我们未加任何修饰执行此代码时,其执行后所用时间如图(摘抄主要):
Function | Callee Exclusive Time |
main | 1.495306 |
IndexOf( String, int32 ) | 0.771013 |
insertChar( String, int32, String, int32 ) | 0.444054 |
我们再来看
for (int i = 0; i < replacement->Length; i++) {
data = insertChar(data, loc+i, replacement, i);
// data->Insert(loc + i, replacement->Substring(i, 1));
}
这个也没必要,何必一个一个的插入呢?整体插入就算了。因而可以改为
return data->Insert(loc,replacement);
对于indeof函数,占的时间实在太多,是该解决一下它,在原函数中间是这样的:
for (loc = data->IndexOf(pattern, 0); loc >= 0;
loc = data->IndexOf(pattern, 0)) {
// replace word
data = replace_word(data, loc, pattern->Length, replacement);
}
没必要总是从第一个找起吧!起先我想的是从上一次查找的结束的下一个位置开始查找,但这样有一个问题。例如我们用dd替换cd,有一个字符串为cccd,第一次替换后为ccdd,不应该只是往后找,因为此时前面也出现了cd,故而在这里我们可以从新得到的loc 前 pattern->length处开始查找,再往前开始找没意义。在这里还就是pattern->Length最好在外面用一个变量代替,如pl,放置循环次次都计算pattern->Length(你可能认为编译器足够聪明,但我们不敢保证它在这里“敢”优化,毕竟pattern是个指针,随时可以变,还是我们替他提早优化,参考《深入理解计算机系统》)。
故而这段程序改为:
int location = 0;
int pl = pattern->Length;
// find every occurrence of pattern:
for (loc = data->IndexOf(pattern, 0); loc >= 0;
loc = data->IndexOf(pattern, location)) {
// replace word
int dis = loc - pl;
if (dis >= 0)
{
location = dis;
}
else
{
location = 0;
}
data = replace_word(data, loc, pl, replacement);
改过的程序为:
#include <iostream>
using namespace std;
using namespace System;
using namespace System::IO;
using namespace System::Text;
//String* insertChar(String *data, int loc, String *replacement, int i) {
// return data->Insert(loc, replacement->Substring(i, 1));
//}
String* replace_word(String* data, int loc, int length, String* replacement) {
// delete the pattern string from loc:
data = data->Remove(loc, length);
// insert each character of the replacement string:
//for (int i = 0; i < replacement->Length; i++) {
// data = insertChar(data, loc+i, replacement, i);
// // data->Insert(loc + i, replacement->Substring(i, 1));
//}
return data->Insert(loc,replacement);
//->Insert(loc,replacement)
}
String* string_subst(String *data, String *pattern, String *replacement) {
try {
int loc;
int location = 0;
int pl = pattern->Length;
// find every occurrence of pattern:
for (loc = data->IndexOf(pattern, 0); loc >= 0;
loc = data->IndexOf(pattern, location)) {
// replace word
int dis = loc - pl;
if (dis >= 0)
{
location = dis;
}
else
{
location = 0;
}
data = replace_word(data, loc, pl, replacement);
}
return data;
} catch (Exception *e) {
Console::WriteLine("Error in substitute ");
Console::WriteLine(e->ToString());
return data;
}
}
String* batch_subst(String *data, const char* subs_filename) {
try {
String *subs_file = new String(subs_filename);
StreamReader *subs_reader = new StreamReader(subs_file);
String *pattern, *replacement, *separator;
while (subs_reader->Peek() >= 0) {
pattern = subs_reader->ReadLine();
replacement = subs_reader->ReadLine();
separator = subs_reader->ReadLine();
data = string_subst(data, pattern, replacement);
}
return data;
} catch(Exception* e ) {
Console::WriteLine( "Error in do_substitutions ");
Console::WriteLine( e->ToString());
return data;
}
}
void process_file(const char* filename, const char* subs_filename) {
StreamReader *reader;
StreamWriter *writer;
String *file = new String(filename);
try {
reader = new StreamReader( file );
String *data = reader->ReadToEnd();
data = batch_subst(data, subs_filename);
reader->Close();
// write the data
writer = new StreamWriter(file, false);
writer->Write(data);
writer->Close();
} catch(Exception* e) {
Console::WriteLine( "Error while processing file ");
Console::WriteLine( e->ToString());
}
}
int main(int argc, char *argv[]) {
if (argc < 3) {
cout << "Not enough input arguments" << endl;
cout << "Usage: substitute subs-file src1 src2 ..." << endl;
} else {
for (int i = 2; i < argc; i++) {
process_file(argv[i], argv[1]);
}
}
return 0;
}
我还准备优化那个reader->Close();writer->Close();没必要每次都关闭。但尝试了一下,最终失败。希望看过此文章的人不吝赐教,多多指导,共同学习。
相关文章推荐
- SSD6中Exercise1答案解析
- 【龙书答案】第三章解析(未完成)
- C++使用jsoncpp解析json
- node函数华为笔试题一(含答案解析)
- SAT考试数学填空试题(四) 含答案解析
- Java中级面试题及答案解析(4)
- Java中高级面试题部分答案解析(3)
- 腾讯2012实习生笔试题+答案解析
- 2017年11月11日软考网络工程师案例分析真题及答案解析
- VC/MFC 使用jsoncpp解析json格式内容
- C++解析JSON之jsoncpp
- C++的Json解析库:jsoncpp和boost .
- 使用JsonCpp在android NDK中解析Json
- 100+经典Java面试题及答案解析
- C++的Json解析库:jsoncpp和boost
- 2018 蓝桥杯 省赛 B组 原题 C语言B组 第3题 第九届蓝桥杯真题 +答案+解析
- Sun java认证考试真题答案及部分解析(三)
- SAT数学练习题及详细答案解析(5)
- Python习题1:None-Unique Elements 习题+前三名答案解析(checkio.org)
- 网易游戏2011招聘笔试题+答案解析