2009-06-20 10 views
39

Siempre he admirado el programa uTorrent original. Se veía genial, tenía menos de 64kb, era extremadamente rápido y tenía todas las características que necesitaba. Lamentablemente, el programa es de código cerrado (y se está volviendo cada vez más inflado), así que vengo a Stackoverflow en busca de inspiración.Programación de programas delgados en C++ (como uTorrent) para Windows

¿Qué métodos recomienda para escribir programas rápidos, eficientes en memoria y elegantes en Windows?

Si bien C# (y todo el concepto de .NET) son buenas ideas, estoy más interesado en las respuestas "puristas" y en el desafío de escribir software eficiente y rápido para la plataforma de Windows, al igual que el cliente uTorrent original. No me importa asignar mi propia memoria, hacer mi propia recolección de basura y crear mis propias estructuras de datos.

Recomendaciones sobre libros, artículos, bibliotecas, IDEs (incluso formas eficientes de obtener más cafeína en mi sistema) bienvenidos.

+1

jaja, la parte sobre la cafeína me hizo reír. Bueno, no creo tener una respuesta, pero sé de hecho que los puristas del hardcore recurrirán al ensamblaje, pero la programación de algo tan complicado como un cliente de torrents en ensamblaje sería casi imposible. Creo que si escribió su propio código (se abstuvo de usar cualquier biblioteca) podría obtener fácilmente un programa C/C++ de menos de 64kb. Si escribió en ensamblaje, probablemente podría lograrlo en 1kb. – ldog

+0

AFAIK uTorrent está lleno de compresor, por lo que su tamaño físico es pequeño. Pero en tiempo de ejecución, se descomprime y usa mucha más memoria. El pequeño tamaño ejecutable se logra al evitar el uso de muchas bibliotecas, especialmente la biblioteca estándar de C++ y las instalaciones de flujo, y crear sustitutos escritos específicamente para el programa. (ver artículo en Wikipedia) – Vanuan

+0

Vanuan: "mucha más memoria" es un poco exagerado. Los empacadores ejecutables usualmente logran índices de compresión de hasta 50%, no mucho más. Entonces, mientras μTorrent tiene que ser desempaquetado en la memoria para funcionar, esto tomará alrededor de 500 KiB. Apenas para las máquinas de hoy. – Joey

Respuesta

17

La Biblioteca de plantillas de Windows está orientada a lo que desea hacer. Es un contenedor de C++ ligero y basado en plantillas para la API de Win32. Con él, no tiene que pasar por el dolor de la codificación directa de Win32, pero no agrega muchos sobrecargas como MFC.

8

Si desea optimizar la huella de memoria más pequeña posible y no le importa saltar a través de un montón de aros que el .NET CLR se inventó para que lo ocupe, escriba una aplicación Win32API directa y enganche a GDI+ es el camino a seguir. Petzold fue la referencia definitiva.

Realmente, es una especie de tonto, ya que el tiempo de ejecución de .NET se cargará en la memoria del sistema operativo, ya sea que la aplicación lo use o no, así que también puede vincularlo.

+0

Me parece que el .NET Framework se carga en cada proceso por separado, de la misma manera que cualquier otra colección de DLL. ¿O ha sido cambiado recientemente? –

+8

@Pontus Gagge: su comprensión es incorrecta. Toda la idea de DLL desde atrás en Windows 3.x días fue para evitar cargar el mismo código más de una vez en la memoria. Win16 y Win32 comparten el código DLL entre los procesos (aunque a través de diferentes mecanismos). Las DLL aparecen en cada espacio de direcciones del proceso a través de la magia de la memoria virtual, pero en realidad solo hay una instancia del código DLL en la memoria. –

+1

.NET todavía incurre en una sobrecarga de memoria debido a la administración automática de la memoria. Además, ¿por qué usar GDI + a menos que quieras dibujar algo (lentamente)? – Joey

5

General: Para ejecutables más pequeños, #define WIN32_LEAN_AND_MEAN y VC_EXTRALEAN (suponiendo VS). No compile con símbolos de depuración (probablemente lo sabía). Utilice menos bibliotecas y conviértase en usuario para vincular solo las partes de las bibliotecas que necesita (el enlazador de VC es bastante bueno al respecto, pero no toque optlink si puede ayudarlo).

Elimine los encabezados de reubicación: Vaya a http://www.paehl.de/cms/oldtools y busque "ReduceEXE" (enlace de descarga directa: http://www.paehl.de/reduce.zip).

Ejecutar un empaquetador ejecutable: http://upx.sourceforge.net/ ... Utiliza más memoria en el tiempo de ejecución y se inicia un poco más lento, pero el archivo es MUCHO más pequeño.

Si le preocupa más el tamaño del archivo que la velocidad, VC tiene una opción para "optimizar el tamaño", lo que desactiva algunas cosas como el desenrollado del bucle y la función de inserción.

Si quiere ser duro (y no le importan todas las ventajas de ingeniería de software), intente utilizar menos clases, prefiriendo tipos de TPV sin funciones virtuales. Wikipedia sugiere que entre el 6% y el 13% del tiempo de ejecución de un programa se dedica a realizar llamadas virtuales. Además, los propios vtables ocupan (un poco) memoria, y el valor de memoria de size_t al comienzo de cada instancia de clase (que tiene una función virtual) se asigna para el puntero vtable. IOW, "pure C" puede terminar siendo un poco más rápido (aunque si te encuentras emulando clases con punteros a funciones, vuelve a C++).

+0

"No compilar con símbolos de depuración": los símbolos de depuración se crean en un archivo PDB externo. No hay ninguna razón para no generarlos ni siquiera para compilaciones de versiones (ver http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/06/19/do-pdb-files-affect-performance.aspx) "Si le preocupa más el tamaño del archivo que la velocidad, VC tiene una opción para 'optimizar el tamaño'" - esto realmente se convierte en un rendimiento de velocidad más a menudo que no - el tamaño más pequeño produce menos fallas de caché y página. –

+3

@On Freund - No necesariamente - No mencionó específicamente VC++. VC implementa la información de depuración como un PDB, sin embargo, si compila con, digamos DMC o MinGW GCC, la información de depuración se incluye en los archivos del objeto. –

7

Demo Scene es un grupo de personas que pasan su tiempo libre tratando de hacer ejecutables impresionantes y muy pequeños, que generalmente hacen algo en 3d a la música. A menudo, toda la demostración (código, música, datos en 3D) se compila en un solo ejecutable comprimido a 64k o de un tamaño impresionantemente pequeño para el contenido.

Puede inspirarse en las demostraciones y aprender cómo se crearán le informará a su obsesión de crear pequeños ejecutables.

A menudo, la clave es aprovechar la mayor cantidad de archivos DLL de terceros que se instalen con Windows. Además, se requiere una codificación personalizada de bajo nivel de todo lo demás.

10

uTorrent está escrito en C++ y utiliza la antigua API de Win32. Google Chrome también está escrito de esta manera, ¿por qué no descargar el código fuente y aprender de su código?

+1

sí, estoy de acuerdo con usted. intente aprender Win32 API y luego podrá crear aplicaciones pequeñas y rápidas. en el pasado yo estaba usando Delphi, podría crear aplicaciones de pequeño tamaño y bastante fácil de aprender (lenguaje Pascal) – nightingale2k1

+0

+1 para Pascal;) –

1

Notepad++ es también un programa de sistema operativo muy rápido, altamente optimizado y muy útil que podría inspirarle. Su filosofía es similar a la de uTorrent. Utiliza la antigua api de Win32 que todavía debería ser la más rápida que pueda ir a en Windows.

Si quiere ser realmente artístico, la escena demo es el lugar perfecto para go. Aunque su código no siempre está abierto.

+1

No puedo estar totalmente de acuerdo con "Notepad ++ es muy rápido, altamente optimizado" . A veces es lo suficientemente lento en archivos grandes. Y los últimos lanzamientos fueron un poco problemáticos. Otro editor ligero y rápido es AkelPad - http://akelpad.sf.net/ (Es ~ 100k en el paquete exe y ~ 250K en los complementos empaquetados) – zxcat

5

El viejo truco de "LIBCTiny" todavía funciona. Con las versiones modernas de VC++, es posible que necesite activar algunas funciones.

Otro buen truco para saber es la colección de funciones lstr* en Kernel32. Eso ya está en la memoria, por lo que esas funciones podrían ser una opción más sencilla.

Cuestiones relacionadas