Jump to page: 1 2
Thread overview
[your code here]
Jan 31, 2013
Roumen Roupski
Jan 31, 2013
bearophile
Jan 31, 2013
Peter Alexander
Jan 31, 2013
Namespace
Jan 31, 2013
FG
Jan 31, 2013
simendsjo
Jan 31, 2013
Namespace
Jan 31, 2013
Vladimir Panteleev
Jan 31, 2013
bearophile
Jan 31, 2013
FG
Jan 31, 2013
bearophile
Jan 31, 2013
FG
Jan 31, 2013
Ali Çehreli
Jan 31, 2013
Andrej Mitrovic
Jan 31, 2013
Ali Çehreli
Jan 31, 2013
Timon Gehr
Jan 31, 2013
Ali Çehreli
Jan 31, 2013
Maxim Fomin
January 31, 2013
// 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
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
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
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
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
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
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
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
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
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