View mode: basic / threaded / horizontal-split · Log in · Help
January 31, 2013
[your code here]
// Checks if two files have equal content using memory mapped 
files
import std.file;
import std.mmfile;
import std.stdio;

// Compares the content of two files
private bool equals(in string f1, in string f2)
{
	if (getSize(f1) != getSize(f2))
		return false;	// different file sizes

	if (getSize(f1) == 0)
		return true;	// zero-length files are equal
	
	MmFile m1, m2;
	try
	{
		m1 = new MmFile(f1);
		m2 = new MmFile(f2);
		return m1[] == m2[];
	}
	catch (Throwable ex)
	{
		writefln("File read error: %s", ex.msg);
		return false;  // cannot compare the files
	}
	finally
	{
		delete m1;
		delete m2;
	}
}

void main (string[] args)
{
	enum NotFound = "Cannot open file: %s";

	if (args.length == 3)
	{
		auto f1 = args[1], f2 = args[2];

		if (!(exists(f1) && isFile(f1)))
			writefln(NotFound, f1);
		else if (!(exists(f2) && isFile(f2)))
			writefln(NotFound, f2);
		else if (equals(f1, f2))
			writeln("Same files");
		else
			writeln("Different files");
	}
	else
	{
		writeln("Usage: filequals <file1> <file2>");
	}
}
January 31, 2013
Re: [your code here]
Roumen Roupski:

> private bool equals(in string f1, in string f2)
> {
> 	if (getSize(f1) != getSize(f2))
> 		return false;	// different file sizes
>
> 	if (getSize(f1) == 0)
> 		return true;	// zero-length files are equal

Making equals() private is not useful, but maybe it's possible to 
make equals() nothrow.


> 	
> 	MmFile m1, m2;
> 	try
> 	{
> 		m1 = new MmFile(f1);
> 		m2 = new MmFile(f2);
> 		return m1[] == m2[];
> 	}

I have tried your little program on two files about 500 MBytes 
long, and the memory usage is strange. Is it doing the right 
thing?

Bye,
bearophile
January 31, 2013
Re: [your code here]
On Thursday, 31 January 2013 at 08:42:48 UTC, Roumen Roupski 
wrote:
> 	finally
> 	{
> 		delete m1;
> 		delete m2;
> 	}

D has a GC. No need for manual deletion.

(In fact, I think this is deprecated? Or scheduled for removal? 
Or maybe neither. Who knows).
January 31, 2013
Re: [your code here]
On Thursday, 31 January 2013 at 10:58:48 UTC, Peter Alexander 
wrote:
> On Thursday, 31 January 2013 at 08:42:48 UTC, Roumen Roupski 
> wrote:
>> 	finally
>> 	{
>> 		delete m1;
>> 		delete m2;
>> 	}
>
> D has a GC. No need for manual deletion.
>
> (In fact, I think this is deprecated? Or scheduled for removal? 
> Or maybe neither. Who knows).

http://dlang.org/deprecate.html#delete

If you want to do something, then take destroy.
AFAIK delete destroy _and_ release the memory immediately. 
'destroy' doesn't.
January 31, 2013
Re: [your code here]
On 2013-01-31 12:38, Namespace wrote:
> If you want to do something, then take destroy.
> AFAIK delete destroy _and_ release the memory immediately. 'destroy' doesn't.

And that's why delete is valuable (at least on 32-bit windows).
Especially when you are comparing 500 MB files in a loop. :)
January 31, 2013
Re: [your code here]
On Thursday, 31 January 2013 at 12:28:43 UTC, FG wrote:
> On 2013-01-31 12:38, Namespace wrote:
>> If you want to do something, then take destroy.
>> AFAIK delete destroy _and_ release the memory immediately. 
>> 'destroy' doesn't.
>
> And that's why delete is valuable (at least on 32-bit windows).
> Especially when you are comparing 500 MB files in a loop. :)

Run GC.collect() After destroy.
January 31, 2013
Re: [your code here]
On Thursday, 31 January 2013 at 12:28:43 UTC, FG wrote:
> On 2013-01-31 12:38, Namespace wrote:
>> If you want to do something, then take destroy.
>> AFAIK delete destroy _and_ release the memory immediately. 
>> 'destroy' doesn't.
>
> And that's why delete is valuable (at least on 32-bit windows).
> Especially when you are comparing 500 MB files in a loop. :)

I like and use it also. ;)

> Run GC.collect() After destroy.

collect? Maybe free, but collect seems a bit like to take a 
sledgehammer to crack a nut.
January 31, 2013
Re: [your code here]
On Thursday, 31 January 2013 at 12:28:43 UTC, FG wrote:
> On 2013-01-31 12:38, Namespace wrote:
>> If you want to do something, then take destroy.
>> AFAIK delete destroy _and_ release the memory immediately. 
>> 'destroy' doesn't.
>
> And that's why delete is valuable (at least on 32-bit windows).
> Especially when you are comparing 500 MB files in a loop. :)

If we are talking about memory mapped files, then destroying the 
MmFile classes will close the mappings, thus freeing the virtual 
memory.

Anyway, I'm really impressed by this example, as the kernel may 
be inclined to leave the pages we've already compared in RAM 
(might be fixed with madvise(MADV_SEQUENTIAL)), and it doesn't 
demonstrate many D strengths (memory-mapped files are an OS 
feature, for which D just provides a wrapper class). Maybe it 
would be more interesting if we use std.algorithm.zip or 
.lockstep or .equal with File.byChunk?
January 31, 2013
Re: [your code here]
FG:

> Especially when you are comparing 500 MB files in a loop. :)

I have had problems comparing with this program a single pair of 
files that large...

Bye,
bearophile
January 31, 2013
Re: [your code here]
On 2013-01-31 14:21, bearophile wrote:
>> Especially when you are comparing 500 MB files in a loop. :)
>
> I have had problems comparing with this program a single pair of files that
> large...

Strange. No problems here. Only had to switch from dmd32 to gdc64 with 1GB or 
bigger files. Tested on win7-64.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home