CopiaFileTrovati now copies with Parallel.ForEach (degree 6) instead of sequentially: the bottleneck is network latency to the share, not CPU, so overlapping copies gives a large speedup (~5x in a synthetic benchmark with simulated SMB latency, documented in docs/copia-raw-parallela.md). Also adds docs/architettura.md, a full architecture overview of every source file, the wizard's 5 phases, dialogs, persistence and standalone scripts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
47 lines
2.3 KiB
Markdown
47 lines
2.3 KiB
Markdown
# Copia parallela dei file in `raw/`
|
|
|
|
`Form1.CopiaFileTrovati` (usata in fase 3 "Crea cartella raw" e in fase 4 "Trova componenti
|
|
referenziati" per copiare i file trovati nell'indice dentro `raw/`) copia i file in parallelo
|
|
invece che uno alla volta.
|
|
|
|
## Perché
|
|
|
|
I file vengono letti da una share di rete (`X:\`, vedi CLAUDE.md). Il tempo per ogni copia è
|
|
dominato dalla latenza di rete (round-trip SMB per aprire/leggere/chiudere il file), non dalla
|
|
CPU: un thread passa la maggior parte del tempo in attesa della risposta del server. Copiare
|
|
più file in parallelo sovrappone queste attese invece di sommarle, con un guadagno quasi
|
|
proporzionale al grado di parallelismo.
|
|
|
|
## Implementazione
|
|
|
|
`Parallel.ForEach` con `MaxDegreeOfParallelism = 6` (non un thread per file: troppa
|
|
concorrenza sulla stessa share rischia di saturare le connessioni SMB o subire throttling dal
|
|
server, risultando più lento invece che più veloce). Il contatore dei file copiati usa
|
|
`Interlocked.Increment` per essere thread-safe. La logica di skip per file irraggiungibili
|
|
(share offline, permessi — `catch (IOException or UnauthorizedAccessException)`) resta
|
|
invariata: essendo dentro il corpo della lambda, ogni iterazione ha il proprio try/catch
|
|
indipendente.
|
|
|
|
Il valore 6 è una stima di partenza, non misurata sulla share reale: se in pratica risulta
|
|
troppo aggressivo o troppo conservativo per la vostra rete, va aggiustato empiricamente.
|
|
|
|
## Benchmark (sintetico)
|
|
|
|
Non essendoci accesso diretto alla share `X:\` da questo ambiente, il confronto prima/dopo è
|
|
stato fatto con uno script standalone (`dotnet run <file>.cs`, pattern già usato in `scripts/`)
|
|
che copia file locali fittizi aggiungendo un ritardo artificiale di 80 ms per file, per simulare
|
|
la latenza di un round-trip SMB (il disco locale da solo è troppo veloce per mostrare qualunque
|
|
differenza).
|
|
|
|
50 file, ritardo simulato 80 ms/file:
|
|
|
|
| Versione | Tempo totale |
|
|
|---|---|
|
|
| Prima (sequenziale) | 4751 ms |
|
|
| Ora (parallela, grado 6) | 961 ms |
|
|
|
|
~5x più veloce, coerente con l'aspettativa teorica (limite di ~6x dato il grado di
|
|
parallelismo, scontato l'overhead di scheduling). Essendo una simulazione, il guadagno reale
|
|
sulla share va verificato sul campo: la latenza effettiva, la banda disponibile e il
|
|
comportamento del server sotto più connessioni concorrenti possono cambiare il risultato.
|