用Reflector分析一下Xml相关的各个类,我们会发现XmlDocument实际上是利用XmlReader来解析Xml文件的,同时还会同时构造每一个节点,比如XmlElement或者XmlAttribute。很明显XmlDocument肯定不会比XmlReader更加有效率,至少XmlDocument还需要构造一系列的对象,并且还是递归的。如果我们能够减少节点的层次,或者尽量封闭节点(使之不具备拥有子节点的资格,例如把XmlElement的数据挪到XmlAttribute里面),那么XmlDocument的效率会有一定层次的提高。如果说数据量不是非常大(大概100左右),不希望用复杂的方式来完成本来应该很简单的事情,那么这个方法也值得尝试。
<
Root
>
< Item id = "1" name = "hello" something = "xxx" extension = "yyy" abc = "efg" > Text </ Item >
< Item id = "2" name = "world" something = "zzz" type = "reference" extension = "123" > China </ Item >
……
</ Root >
< Item id = "1" name = "hello" something = "xxx" extension = "yyy" abc = "efg" > Text </ Item >
< Item id = "2" name = "world" something = "zzz" type = "reference" extension = "123" > China </ Item >
……
</ Root >
有的时候我们也需不愿意,或者无法进行文件分割,比如说所有的数据都必须要加载了才能够计算,又或者我们不能够冒分割文件所带来的一些技术风险,那么也许我们需要考虑用自己的文件格式来保存了,比如说二进制(也许文本方式也是一个不错的选择,我说的是纯文本)。如果您同意了我这个假设成立,那么我们可以开始着手研究一下有关文件读取方面的问题。不要以为这是一个简单的问题,我之前也以为这是一个很简单的问题,而最后我却发现这个问题要看硬件平台如何。我一年前在PC上面做应用,感觉文件读取和内存读取效率相差不大。当时我就猜测由于PDA的文件在内存当中,因此不会像桌面PC一样,文件的读取效率和内存的读取效率相差上千倍,顶多相差十倍。而当时的工作经验告诉我似乎结果就是这样的,因为我在PDA上面读取文件几乎就没有遇到什么性能瓶颈。然而这一次在SmartPhone上面的情况却完全不一样,让我大吃一惊。如果有机会大家可以在SmartPhone上面运行一下如下的代码片断,保证有一个深刻的体会:
void
Test()
{
// Create an 1MB file for testing, make the buffer size of filestream object to 640k
FileStream fs = new FileStream(
"Test.Binary",
FileMode.Create,
FileAccess.ReadWrite,
FileShare.None,
655360
);
byte[] buff = new byte[1048576];
fs.Write(buff, 0, buff.Length);
long ticks;
// Reset the position
fs.Position = 0;
BinaryReader br = new BinaryReader(fs);
// Test reading every byte from BinaryReader using for statement:
ticks = DateTime.Now.Ticks;
for(i = 0; i < buff.Length; i++)
{
br.ReadByte();
}
ticks = DateTime.Now.Ticks - ticks;
MessageBox.Show(ticks.ToString());
// Reset the position and test reading every byte using while statement:
fs.Position = 0;
ticks = DateTime.Now.Ticks;
while (fs.Position != fs.Length)
{
br.ReadByte();
}
ticks = DateTime.Now.Ticks - ticks;
MessageBox.Show(ticks.ToString());
// Reset the position and test reading via MemoryStream
// using while statement:
fs.Position = 0;
ticks = DateTime.Now.Ticks;
// we define another buffer to test mem alloc time all together
byte[] buffRead = new byte[buff.Length];
fs.Read(buffRead, 0, buffRead.Length);
MemoryStream ms = new MemoryStream(buffRead);
br = new BinaryReader(ms);
while (ms.Position != ms.Length)
{
br.ReadByte();
}
ticks = DateTime.Now.Ticks - ticks;
MessageBox.Show(ticks.ToString());
fs.Close();
}
{
// Create an 1MB file for testing, make the buffer size of filestream object to 640k
FileStream fs = new FileStream(
"Test.Binary",
FileMode.Create,
FileAccess.ReadWrite,
FileShare.None,
655360
);
byte[] buff = new byte[1048576];
fs.Write(buff, 0, buff.Length);
long ticks;
// Reset the position
fs.Position = 0;
BinaryReader br = new BinaryReader(fs);
// Test reading every byte from BinaryReader using for statement:
ticks = DateTime.Now.Ticks;
for(i = 0; i < buff.Length; i++)
{
br.ReadByte();
}
ticks = DateTime.Now.Ticks - ticks;
MessageBox.Show(ticks.ToString());
// Reset the position and test reading every byte using while statement:
fs.Position = 0;
ticks = DateTime.Now.Ticks;
while (fs.Position != fs.Length)
{
br.ReadByte();
}
ticks = DateTime.Now.Ticks - ticks;
MessageBox.Show(ticks.ToString());
// Reset the position and test reading via MemoryStream
// using while statement:
fs.Position = 0;
ticks = DateTime.Now.Ticks;
// we define another buffer to test mem alloc time all together
byte[] buffRead = new byte[buff.Length];
fs.Read(buffRead, 0, buffRead.Length);
MemoryStream ms = new MemoryStream(buffRead);
br = new BinaryReader(ms);
while (ms.Position != ms.Length)
{
br.ReadByte();
}
ticks = DateTime.Now.Ticks - ticks;
MessageBox.Show(ticks.ToString());
fs.Close();
}
待续……